/* void VPictureData_GDIPlus_Vector::FromVFile(VFile& inFile) { Gdiplus::Rect rect; SetDataSource(NULL,true); _DisposeMetaFile(); _SetDecoderByExtension("emf"); VString path; inFile.GetPath(path); fMetafile=new Gdiplus::Metafile(path.GetCPointer()); _InitSize(); } */ void VPictureData_GDIPlus_Vector::_FromMetaFilePict(METAFILEPICT* inMetaPict) { HENHMETAFILE henh; void* lpWinMFBits; UINT uiSizeBuf; uiSizeBuf = GetMetaFileBitsEx(inMetaPict->hMF, 0, NULL); lpWinMFBits = GlobalAllocPtr(GHND, uiSizeBuf); GetMetaFileBitsEx(inMetaPict->hMF, uiSizeBuf, (LPVOID)lpWinMFBits); henh = SetWinMetaFileBits(uiSizeBuf, (LPBYTE)lpWinMFBits, NULL, inMetaPict); GlobalFreePtr(lpWinMFBits); _FromEnhMetaFile(henh); }
/****************************************************************** * create_metafile16 * * Create a 16-bit metafile from a 32-bit one. The 32-bit one is deleted. */ static HMETAFILE16 create_metafile16( HMETAFILE hmf ) { UINT size; HMETAFILE16 hmf16; if (!hmf) return 0; size = GetMetaFileBitsEx( hmf, 0, NULL ); hmf16 = GlobalAlloc16( GMEM_MOVEABLE, size ); if (hmf16) { void *buffer = GlobalLock16( hmf16 ); GetMetaFileBitsEx( hmf, size, buffer ); GlobalUnlock16( hmf16 ); } DeleteMetaFile( hmf ); return hmf16; }
/****************************************************************************** * OleMetaFilePictFromIconAndLabel (OLE2.56) * * Returns a global memory handle to a metafile which contains the icon and * label given. * I guess the result of that should look somehow like desktop icons. * If no hIcon is given, we load the icon via lpszSourceFile and iIconIndex. * This code might be wrong at some places. */ HGLOBAL16 WINAPI OleMetaFilePictFromIconAndLabel16( HICON16 hIcon, LPCOLESTR16 lpszLabel, LPCOLESTR16 lpszSourceFile, UINT16 iIconIndex ) { METAFILEPICT16 *mf16; HGLOBAL16 hmf16; HMETAFILE hmf; INT mfSize; HDC hdc; if (!hIcon) { if (lpszSourceFile) { HINSTANCE16 hInstance = LoadLibrary16(lpszSourceFile); /* load the icon at index from lpszSourceFile */ hIcon = HICON_16(LoadIconA(HINSTANCE_32(hInstance), (LPCSTR)(DWORD)iIconIndex)); FreeLibrary16(hInstance); } else return 0; } FIXME("(%04x, '%s', '%s', %d): incorrect metrics, please try to correct them !\n", hIcon, lpszLabel, lpszSourceFile, iIconIndex); hdc = CreateMetaFileW(NULL); DrawIcon(hdc, 0, 0, HICON_32(hIcon)); /* FIXME */ TextOutA(hdc, 0, 0, lpszLabel, 1); /* FIXME */ hmf = CloseMetaFile(hdc); hmf16 = GlobalAlloc16(0, sizeof(METAFILEPICT16)); mf16 = (METAFILEPICT16 *)GlobalLock16(hmf16); mf16->mm = MM_ANISOTROPIC; mf16->xExt = 20; /* FIXME: bogus */ mf16->yExt = 20; /* dito */ mfSize = GetMetaFileBitsEx(hmf, 0, 0); mf16->hMF = GlobalAlloc16(GMEM_MOVEABLE, mfSize); if(mf16->hMF) { GetMetaFileBitsEx(hmf, mfSize, GlobalLock16(mf16->hMF)); GlobalUnlock16(mf16->hMF); } return hmf16; }
void VPictureData_EMF::FromMetaFilePict(METAFILEPICT* inMetaPict) { HENHMETAFILE henh; _ReleaseDataProvider(); _DisposeMetaFile(); void* lpWinMFBits; UINT uiSizeBuf; uiSizeBuf = GetMetaFileBitsEx(inMetaPict->hMF, 0, NULL); lpWinMFBits = GlobalAllocPtr(GHND, uiSizeBuf); GetMetaFileBitsEx(inMetaPict->hMF, uiSizeBuf, (LPVOID)lpWinMFBits); henh = SetWinMetaFileBits(uiSizeBuf, (LPBYTE)lpWinMFBits, NULL, inMetaPict); GlobalFreePtr(lpWinMFBits); FromEnhMetaFile(henh); }
/* * clipboard_file_to_data - ファイルからデータを作成 */ HANDLE clipboard_file_to_data(const TCHAR *file_name, TCHAR *format_name, DWORD *ret_size, TCHAR *err_str) { HANDLE ret = NULL; BYTE *data; BYTE *mem; DWORD size; switch (clipboard_get_format(0, format_name)) { case CF_OWNERDISPLAY: return NULL; case CF_DSPMETAFILEPICT: case CF_METAFILEPICT: // メタファイル if ((ret = GlobalAlloc(GHND, sizeof(METAFILEPICT))) == NULL) { message_get_error(GetLastError(), err_str); return NULL; } if ((mem = GlobalLock(ret)) == NULL) { message_get_error(GetLastError(), err_str); GlobalFree(ret); return NULL; } if ((((METAFILEPICT *)mem)->hMF = GetMetaFile(file_name)) == NULL) { message_get_error(GetLastError(), err_str); GlobalUnlock(ret); GlobalFree(ret); return NULL; } size = GetMetaFileBitsEx(((METAFILEPICT *)mem)->hMF, 0, NULL); GlobalUnlock(ret); break; case CF_DSPENHMETAFILE: case CF_ENHMETAFILE: if ((ret = GetEnhMetaFile(file_name)) == NULL) { message_get_error(GetLastError(), err_str); } size = GetEnhMetaFileBits(ret, 0, NULL); break; default: // その他 // ファイルの読み込み if ((data = file_read_buf(file_name, &size, err_str)) == NULL) { return NULL; } // バイト列をデータに変換 ret = clipboard_bytes_to_data(format_name, data, &size); mem_free(&data); break; } if (ret_size != NULL) { *ret_size = size; } return ret; }
static HENHMETAFILE ReadEnhMetaFile(const char *path,long *width, long *height) { #pragma pack( push ) #pragma pack( 2 ) typedef struct { DWORD dwKey; WORD hmf; SMALL_RECT bbox; WORD wInch; DWORD dwReserved; WORD wCheckSum; } APMHEADER, *PAPMHEADER; #pragma pack( pop ) DWORD dwSize; ENHMETAHEADER emfh; HANDLE hFile; HDC hDC; HENHMETAFILE hTemp; LPBYTE pBits; METAFILEPICT mp; HMETAFILE hOld; *width=512; *height=512; hTemp=GetEnhMetaFile(path); #if defined(MAGICKCORE_HAVE__WFOPEN) if (hTemp == (HENHMETAFILE) NULL) { wchar_t *unicode_path; unicode_path=ConvertUTF8ToUTF16(path); if (unicode_path != (wchar_t *) NULL) { hTemp=GetEnhMetaFileW(unicode_path); unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path); } } #endif if (hTemp != (HENHMETAFILE) NULL) { /* Enhanced metafile. */ GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } hOld=GetMetaFile(path); if (hOld != (HMETAFILE) NULL) { /* 16bit windows metafile. */ dwSize=GetMetaFileBitsEx(hOld,0,NULL); if (dwSize == 0) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits)); if (pBits == (LPBYTE) NULL) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0) { pBits=(BYTE *) DestroyString((char *) pBits); DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the windows metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=1000; mp.yExt=1000; mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp); ReleaseDC(NULL,hDC); DeleteMetaFile(hOld); pBits=(BYTE *) DestroyString((char *) pBits); GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } /* Aldus Placeable metafile. */ hFile=CreateFile(path,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return(NULL); dwSize=GetFileSize(hFile,NULL); pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits)); ReadFile(hFile,pBits,dwSize,&dwSize,NULL); CloseHandle(hFile); if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l) { pBits=(BYTE *) DestroyString((char *) pBits); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the placable metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left; *width=mp.xExt; mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top; *height=mp.yExt; mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp); ReleaseDC(NULL,hDC); pBits=(BYTE *) DestroyString((char *) pBits); return(hTemp); }
STDMETHODIMP CDropTarget::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) { #ifdef _DEBUG printf("IDropTarget::Drop\n"); #endif //_DEBUG DWORD dwOKEffects = *pdwEffect; { //We do this because grfKeyState will always have the mouse button used off DWORD temp = LastKeyState; //Get the position of the drop DragOver(grfKeyState, pt, pdwEffect); LastKeyState = temp; } //Remove the effects pDataObj = NULL; DragLeave(); bool copying = (*pdwEffect & DROPEFFECT_COPY) != 0; size_t totallen = 0; BYTE *data = NULL; bool gotdata = false; UINT *formats = NULL; UINT numformats = 0; FORMATETC *fel = NULL; UINT numfe = 0; bool NeedToChooseFormat = true; int IndexOfDataToInsert = -1; bool NeedToChooseMoveorCopy = (LastKeyState | grfKeyState) & (MK_MBUTTON | MK_RBUTTON) || hexwnd.always_pick_move_copy; if (hexwnd.dragging) // Internal data { hexwnd.dragging = FALSE; if (NeedToChooseMoveorCopy) { int choice = PopupDropMenu(pt); if (choice == 0) { pDataObject->Release(); *pdwEffect = DROPEFFECT_NONE; return S_OK; } copying = choice != 1; } int iMove1stEnd = hexwnd.iGetStartOfSelection(); int iMove2ndEndorLen = hexwnd.iGetEndOfSelection(); int iMovePosOrg = hexwnd.new_pos; if (!copying && hexwnd.new_pos > iMove2ndEndorLen) hexwnd.new_pos += iMove1stEnd - iMove2ndEndorLen - 1; iMovePos = hexwnd.new_pos; iMoveOpTyp = copying ? OPTYP_COPY : OPTYP_MOVE; SimpleArray<BYTE> olddata; const int len = iMove2ndEndorLen - iMove1stEnd + 1; if (grfKeyState & MK_SHIFT) // Overwrite { if (copying) { //Just [realloc &] memmove if (iMovePos + len > hexwnd.m_dataArray.GetLength()) // Need more space { olddata.AppendArray(&hexwnd.m_dataArray[iMovePos], hexwnd.m_dataArray.GetLength() - iMovePos); if (hexwnd.m_dataArray.SetSize(iMovePos + len)) { hexwnd.m_dataArray.ExpandToSize(); memmove(&hexwnd.m_dataArray[iMovePos], &hexwnd.m_dataArray[iMove1stEnd], len); } } else // Enough space { olddata.AppendArray(&hexwnd.m_dataArray[iMovePos], len); memmove(&hexwnd.m_dataArray[iMovePos], &hexwnd.m_dataArray[iMove1stEnd], len); } hexwnd.push_undorecord(iMovePos, olddata, olddata.GetLength(), &hexwnd.m_dataArray[iMovePos], len); } else //Moving { if (iMovePos > iMove1stEnd) //Forward { olddata.AppendArray(&hexwnd.m_dataArray[iMove1stEnd], iMovePosOrg + len - iMove1stEnd); hexwnd.move_copy_sub(iMove1stEnd, iMove2ndEndorLen, 0); hexwnd.m_dataArray.RemoveAt(iMovePos+len,len); hexwnd.push_undorecord(iMove1stEnd, olddata, olddata.GetLength(), &hexwnd.m_dataArray[iMove1stEnd], iMovePosOrg - iMove1stEnd); } else //Backward { if (iMove1stEnd-iMovePos>=len) { olddata.AppendArray(&hexwnd.m_dataArray[iMovePos], iMove1stEnd + len - iMovePos); memmove(&hexwnd.m_dataArray[iMovePos],&hexwnd.m_dataArray[iMove1stEnd],len); hexwnd.m_dataArray.RemoveAt(iMove1stEnd,len); } else { olddata.AppendArray(&hexwnd.m_dataArray[iMovePos], iMove1stEnd + len - (iMovePos + len - iMove1stEnd) - iMovePos); memmove(&hexwnd.m_dataArray[iMovePos],&hexwnd.m_dataArray[iMove1stEnd],len); hexwnd.m_dataArray.RemoveAt(iMovePos+len,len-(iMovePos + len - iMove1stEnd)); } hexwnd.push_undorecord(iMovePos, olddata, olddata.GetLength(), &hexwnd.m_dataArray[iMovePos], iMove1stEnd - iMovePos); } } hexwnd.iStartOfSelection = iMovePos; hexwnd.iEndOfSelection = iMovePos+len-1; hexwnd.bFilestatusChanged = true; hexwnd.bSelected = true; hexwnd.resize_window(); } else // Insert { hexwnd.CMD_move_copy(iMove1stEnd, iMove2ndEndorLen, 1); } } else // External data { STGMEDIUM stm; HRESULT err = E_UNEXPECTED; //Get the formats enumerator IEnumFORMATETC *iefe = 0; pDataObject->EnumFormatEtc(DATADIR_GET, &iefe); if (iefe == 0) { #ifdef _DEBUG printf("Unable to create a drag-drop data enumerator\n"); #endif //_DEBUG goto ERR; } iefe->Reset(); //Get the available formats for(;;) { void *temp = realloc(fel, (numfe + 1) * sizeof(FORMATETC)); if (temp != NULL) { fel = (FORMATETC*) temp; temp = NULL; int r; r = iefe->Next(1, &fel[numfe], NULL); if (r != S_OK) break;//No more formats numfe++; } else if (fel == NULL) { //We only go here if nothing could be allocated #ifdef _DEBUG printf("Not enough memory for the drag-drop format list\n"); #endif //_DEBUG goto ERR_ENUM; } } UINT i; /*Check which format should be inserted according to user preferences*/ if (numfe == 0) { MessageBox(hexwnd.pwnd, GetLangString(IDS_DD_NO_DATA), MB_OK); err = S_OK; *pdwEffect = DROPEFFECT_NONE; goto ERR_ENUM; } if (hexwnd.prefer_CF_HDROP) { for (i = 0 ; i < numfe ; i++) { if (fel[i].cfFormat == CF_HDROP) { //Return no effect & let shell32 handle it if (S_OK == pDataObject->GetData(&fel[i], &stm)) { hexwnd.dropfiles((HDROP)stm.hGlobal); } err = S_OK; *pdwEffect = DROPEFFECT_NONE; goto ERR_ENUM; } } } if (numfe == 1) { IndexOfDataToInsert = 0; } else if (hexwnd.prefer_CF_BINARYDATA) { for (i = 0 ; i < numfe ; i++) { if (fel[i].cfFormat == CF_BINARYDATA) { NeedToChooseFormat = false; IndexOfDataToInsert = i; break; } } } else if (hexwnd.prefer_CF_TEXT) { for (i = 0 ; i < numfe ; i++) { if (fel[i].cfFormat == CF_TEXT) { NeedToChooseFormat = false; IndexOfDataToInsert = i; break; } } } if (NeedToChooseFormat) { dialog<DragDropDlg> params; params.allowable_effects = dwOKEffects & (DROPEFFECT_COPY | DROPEFFECT_MOVE); params.effect = copying; params.formatetcs = fel; params.numformatetcs = numfe; params.formats = NULL; params.numformats = 0; int ret = params.DoModal(hexwnd.pwnd); if (ret < 0) { //An error occured or the user canceled the operation err = S_OK; *pdwEffect = DROPEFFECT_NONE; goto ERR_ENUM; } numformats = params.numformats; formats = params.formats; copying = params.effect; } else if (NeedToChooseMoveorCopy) { int choice = PopupDropMenu(pt); if (choice == 0) { err = S_OK; *pdwEffect = DROPEFFECT_NONE; goto ERR_ENUM; } copying = choice != 1; } if (IndexOfDataToInsert >= 0 && formats == NULL) { formats = (UINT*)&IndexOfDataToInsert; numformats = 1; } //for each selected format for (i = 0 ; i < numformats ; i++) { FORMATETC fe = fel[formats[i]]; /*It is important that when debugging (with M$VC at least) you do not step __into__ the below GetData call If you do the app providing the data source will die & GetData will return OLE_E_NOTRUNNING or E_FAIL The solution is to step over the call It is also possible that a debugger will be opened & attach itself to the data provider */ if (pDataObject->GetData(&fe, &stm) == S_OK) { //Get len size_t len = 0; switch (stm.tymed) { case TYMED_HGLOBAL: len = GlobalSize(stm.hGlobal); break; #ifndef __CYGWIN__ case TYMED_FILE: { int fh = _wopen(stm.lpszFileName, _O_BINARY | _O_RDONLY); if (fh != -1) { len = _filelength(fh); if (len == (size_t)-1) len = 0; _close(fh); } } break; #endif //__CYGWIN__ case TYMED_ISTREAM: { STATSTG stat; if (S_OK == stm.pstm->Stat(&stat, STATFLAG_NONAME)) len = (size_t)stat.cbSize.LowPart; } break; //This case is going to be a bitch to implement so it can wait for a while //It will need to be a recursive method that stores the STATSTG structures (+ the name), contents/the bytes of data in streams/property sets case TYMED_ISTORAGE: { MessageBox(hexwnd.pwnd, GetLangString(IDS_DD_TYMED_NOTSUP), MB_OK); } break; // IStorage* case TYMED_GDI: { len = GetObject(stm.hBitmap, 0, NULL); if (len) { DIBSECTION t; GetObject(stm.hBitmap, len, &t); len += t.dsBm.bmHeight*t.dsBm.bmWidthBytes*t.dsBm.bmPlanes; } } break; // HBITMAP case TYMED_MFPICT: { len = GlobalSize(stm.hMetaFilePict); METAFILEPICT *pMFP = (METAFILEPICT*)GlobalLock(stm.hMetaFilePict); if (pMFP) { len += GetMetaFileBitsEx(pMFP->hMF, 0, NULL); GlobalUnlock(stm.hMetaFilePict); } } break; // HMETAFILE #ifndef __CYGWIN__ case TYMED_ENHMF: { len = GetEnhMetaFileHeader(stm.hEnhMetaFile, 0, NULL); DWORD n = GetEnhMetaFileDescriptionW(stm.hEnhMetaFile, 0, NULL); if (n && n != GDI_ERROR) len += sizeof(WCHAR) * n; len += GetEnhMetaFileBits(stm.hEnhMetaFile, 0, NULL); n = GetEnhMetaFilePaletteEntries(stm.hEnhMetaFile, 0, NULL); if (n && n != GDI_ERROR) len += sizeof(LOGPALETTE) + (n - 1) * sizeof(PALETTEENTRY); } break; // HENHMETAFILE #endif //__CYGWIN__ //case TYMED_NULL:break; } if (!len) continue; /*Malloc We do this so that if the data access fails we only need free(data) and don't need to mess around with the m_dataArray. Perhaps in the future the m_dataArray can support undoable actions.*/ BYTE* t = (BYTE*)realloc(data, len); if (!t) continue; data = t; memset(data, 0, len); //Get data switch (stm.tymed) { case TYMED_HGLOBAL: { if (LPVOID pmem = GlobalLock(stm.hGlobal)) { memcpy(data, pmem, len); gotdata = true; GlobalUnlock(stm.hGlobal); } } break; #ifndef __CYGWIN__ case TYMED_FILE: { int fh = _wopen(stm.lpszFileName, _O_BINARY | _O_RDONLY); if (fh != -1) { if (0 < _read(fh, data, len)) gotdata = true; _close(fh); } } break; #endif //__CYGWIN__ case TYMED_ISTREAM: { LARGE_INTEGER zero = { 0 }; ULARGE_INTEGER pos; if (S_OK == stm.pstm->Seek(zero, STREAM_SEEK_CUR, &pos)) { stm.pstm->Seek(zero, STREAM_SEEK_SET, NULL); if (S_OK == stm.pstm->Read(data, len, NULL)) gotdata = true; stm.pstm->Seek(*(LARGE_INTEGER*)&pos, STREAM_SEEK_SET, NULL); } } break; //This case is going to be a bitch to implement so it can wait for a while //It will need to be a recursive method that stores the STATSTG structures (+ the name), contents/the bytes of data in streams/property sets case TYMED_ISTORAGE: { MessageBox(hexwnd.pwnd, GetLangString(IDS_DD_TYMED_NOTSUP), MB_OK); goto ERR_ENUM; } break;//IStorage* case TYMED_GDI: { int l = GetObject(stm.hBitmap, len, data); if (l) { BITMAP* bm = (BITMAP*)data; if (bm->bmBits) memcpy(&data[l], bm->bmBits, len-l); else GetBitmapBits(stm.hBitmap, len-l, &data[l]); gotdata = true; } } break; // HBITMAP case TYMED_MFPICT: { if (METAFILEPICT *pMFP = (METAFILEPICT *)GlobalLock(stm.hMetaFilePict)) { memcpy(data, pMFP, sizeof *pMFP); GetMetaFileBitsEx(pMFP->hMF, len - sizeof(*pMFP), &data[sizeof(*pMFP)]); GlobalUnlock(stm.hMetaFilePict); gotdata = true; } } break;//HMETAFILE #ifndef __CYGWIN__ case TYMED_ENHMF: { DWORD i = 0, n = 0, l = len; n = GetEnhMetaFileHeader(stm.hEnhMetaFile, l, (ENHMETAHEADER*)&data[i]); l -= n; i += n; n = GetEnhMetaFileDescriptionW(stm.hEnhMetaFile, l / sizeof(WCHAR), (LPWSTR)&data[i]); if (n && n != GDI_ERROR) { n *= sizeof(WCHAR);l -= n; i += n; } n = GetEnhMetaFileBits(stm.hEnhMetaFile, l, &data[i]); l -= n; i += n; n = GetEnhMetaFilePaletteEntries(stm.hEnhMetaFile, 0, NULL); if (n && n != GDI_ERROR) { LOGPALETTE* lp = (LOGPALETTE*)&data[i]; lp->palVersion = 0x300; lp->palNumEntries = (USHORT)n; l -= sizeof(lp->palVersion) + sizeof(lp->palNumEntries); n = GetEnhMetaFilePaletteEntries(stm.hEnhMetaFile, l / sizeof(PALETTEENTRY), &lp->palPalEntry[0]); i += n*sizeof(PALETTEENTRY); } if (i) gotdata = true; } break; // HENHMETAFILE #endif //__CYGWIN__ //case TYMED_NULL:break; } ReleaseStgMedium(&stm); if (gotdata) { BYTE* DataToInsert = data; if (fe.cfFormat == CF_BINARYDATA) { len = *(DWORD*)data; DataToInsert += 4; } else if (fe.cfFormat == CF_TEXT || fe.cfFormat == CF_OEMTEXT) { len = strlen((char*)data); } else if (fe.cfFormat == CF_UNICODETEXT) { len = sizeof(wchar_t)*wcslen((wchar_t*)data); } // Insert/overwrite data into m_dataArray if (grfKeyState&MK_SHIFT) { /* Overwite */ SimpleArray<BYTE> olddata; DWORD upper = 1 + hexwnd.m_dataArray.GetUpperBound(); if (hexwnd.new_pos+len > upper) { olddata.AppendArray(&hexwnd.m_dataArray[hexwnd.new_pos + (int)totallen], upper - hexwnd.new_pos + (int)totallen); /* Need more space */ if (hexwnd.m_dataArray.SetSize(hexwnd.new_pos + totallen + len)) { hexwnd.m_dataArray.ExpandToSize(); memcpy(&hexwnd.m_dataArray[hexwnd.new_pos + (int)totallen], DataToInsert, len); hexwnd.push_undorecord(hexwnd.new_pos + totallen, olddata, olddata.GetLength(), DataToInsert, len); gotdata = true; totallen += len; } } else { /* Enough space */ olddata.AppendArray(&hexwnd.m_dataArray[hexwnd.new_pos + (int)totallen], len); memcpy(&hexwnd.m_dataArray[hexwnd.new_pos + (int)totallen], DataToInsert, len); hexwnd.push_undorecord(hexwnd.new_pos + totallen, olddata, olddata.GetLength(), DataToInsert, len); gotdata = true; totallen += len; } } else if (hexwnd.m_dataArray.InsertAtGrow(hexwnd.new_pos + totallen, DataToInsert, 0, len)) { /* Insert */ hexwnd.push_undorecord(hexwnd.new_pos + totallen, NULL, 0, DataToInsert, len); gotdata = true; totallen += len; } } } } // For each selected format // Release the data free(data); data = NULL; if (IndexOfDataToInsert < 0) { free(formats); formats = NULL; } if (gotdata) { hexwnd.iStartOfSelection = hexwnd.new_pos; hexwnd.iEndOfSelection = hexwnd.new_pos + totallen - 1; hexwnd.bFilestatusChanged = true; hexwnd.bSelected = true; hexwnd.resize_window(); hexwnd.synch_sibling(); } *pdwEffect = copying ? DROPEFFECT_COPY : DROPEFFECT_MOVE; err = S_OK; ERR_ENUM: iefe->Release(); free(fel); ERR: pDataObject->Release(); return err; } pDataObject->Release(); return S_OK; }
BOOL __stdcall pvdFileOpen2(void *pContext, const wchar_t *pFileName, INT64 lFileSize, const BYTE *pBuf, UINT32 lBuf, pvdInfoImage2 *pImageInfo) { _ASSERTE(pImageInfo->cbSize >= sizeof(pvdInfoImage2)); WmfContext *pw = (WmfContext*)CALLOC(sizeof(WmfContext)); if (!pw) { pImageInfo->nErrNumber = PWE_NOT_ENOUGH_MEMORY; return FALSE; } //pw->h = GetEnhMetaFile ( pFileName+4 ); const wchar_t *p = GetExtension(pFileName); if (!p) { pImageInfo->nErrNumber = PWE_NO_EXTENSION; return FALSE; } pImageInfo->nErrNumber = PWE_WIN32_ERROR; // заранее //if (pImageInfo->PreferredSize.cx && pImageInfo->PreferredSize.cy) { // pw->PreferredSize = pImageInfo->PreferredSize; //} else { pw->PreferredSize.cx = 1000; pw->PreferredSize.cy = 1000; //} // First try to read it as an enhanced metafile // If it works, simply return the handle pw->h = SetEnhMetaFileBits(lBuf, pBuf); gnLastWin32Error = GetLastError(); if (!pw->h) { pw->h = GetEnhMetaFile( pFileName ); gnLastWin32Error = GetLastError(); } if (!pw->h) { HMETAFILE hOld; DWORD dwSize; LPBYTE pBits; METAFILEPICT mp; HDC hDC; if( (hOld = GetMetaFile( pFileName )) != NULL ) { // Ok, it is a 16bit windows metafile // How big are the bits? if( (dwSize = GetMetaFileBitsEx( hOld, 0, NULL )) == 0 ) { gnLastWin32Error = GetLastError(); DeleteMetaFile( hOld ); //MessageBox( hWndParent, "Failed to Get MetaFile Bits Size", "Error Reading MetaFile", MB_OK ); } else { // Allocate that much memory if( (pBits = (LPBYTE)CALLOC( dwSize )) == NULL ) { pImageInfo->nErrNumber = PWE_NOT_ENOUGH_MEMORY; gnLastWin32Error = GetLastError(); DeleteMetaFile( hOld ); //MessageBox( hWndParent, "Failed to Allocate Memory for Metafile Bits", "Error Reading MetaFile", MB_OK ); //return NULL; } else { // Get the metafile bits if( GetMetaFileBitsEx( hOld, dwSize, pBits ) == 0 ) { gnLastWin32Error = GetLastError(); FREE( pBits ); DeleteMetaFile( hOld ); //MessageBox( hWndParent, "Failed to Get MetaFile Bits", "Error Reading MetaFile", MB_OK ); //return NULL; } else { // Fill out a METAFILEPICT structure mp.mm = MM_ANISOTROPIC; mp.xExt = 1000; mp.yExt = 1000; mp.hMF = NULL; // Get a reference DC hDC = GetDC( NULL ); // Make an enhanced metafile from the windows metafile pw->h = SetWinMetaFileBits( dwSize, pBits, hDC, &mp ); gnLastWin32Error = GetLastError(); // Clean up ReleaseDC( NULL, hDC ); DeleteMetaFile( hOld ); FREE( pBits ); } } } } } if (!pw->h) { DWORD dwSize = lBuf; LPBYTE pBits = (LPBYTE)pBuf; METAFILEPICT mp; HDC hDC; // Is it a placeable metafile? (check the key) if( ((PAPMHEADER)pBits)->dwKey != 0x9ac6cdd7l ) { // Not a metafile that we know how to recognise - bail out //MessageBox( hWndParent, "Not a Valid Metafile", szFileName, MB_OK ); //return NULL; pImageInfo->nErrNumber = PWE_NOT_VALID_METAFILE; } else { // Ok, its a placeable metafile // Fill out a METAFILEPICT structure mp.mm = MM_ANISOTROPIC; mp.xExt = ((PAPMHEADER)pBits)->bbox.Right - ((PAPMHEADER)pBits)->bbox.Left; mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(((PAPMHEADER)pBits)->wInch); mp.yExt = ((PAPMHEADER)pBits)->bbox.Bottom - ((PAPMHEADER)pBits)->bbox.Top; mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(((PAPMHEADER)pBits)->wInch); mp.hMF = NULL; // Get a reference DC hDC = GetDC( NULL ); // Create an enhanced metafile from the bits pw->h = SetWinMetaFileBits( dwSize, &(pBits[sizeof(APMHEADER)]), hDC, &mp ); gnLastWin32Error = GetLastError(); // Clean up ReleaseDC( NULL, hDC ); //free( pBits ); //if( hTemp == NULL ) // MessageBox( hWndParent, "Failed to Create MetaFile from Bits", "Error Reading MetaFile", MB_OK ); //return hTemp; } } //if (pw->h) { // //pw->hCompDC = CreateCompatibleDC(NULL); // pw->mfp.mm = MM_ISOTROPIC; // pw->mfp.xExt = pw->PreferredSize.cx; // pw->mfp.yExt = pw->PreferredSize.cy; // pw->h = (HENHMETAFILE)SetMetaFileBitsEx (lBuf, pBuf); // gnLastWin32Error = GetLastError(); // pw->h = SetWinMetaFileBits(lBuf, pBuf, NULL, NULL); //pw->hCompDC, &pw->mfp); // gnLastWin32Error = GetLastError(); //} if (!pw->h) { //gnLastWin32Error = GetLastError(); -- уже FREE(pw); return FALSE; } pw->AddRef(); _ASSERTE(pw->nRefCount == 1); ENHMETAHEADER emh = {0}; DWORD PixelsX, PixelsY, MMX, MMY; emh.nSize = sizeof(ENHMETAHEADER); if( GetEnhMetaFileHeader( pw->h, sizeof( ENHMETAHEADER ), &emh ) ) { // Get the characteristics of the output device HDC hDC = GetDC(NULL); PixelsX = GetDeviceCaps( hDC, HORZRES ); PixelsY = GetDeviceCaps( hDC, VERTRES ); MMX = GetDeviceCaps( hDC, HORZSIZE ) * 100; MMY = GetDeviceCaps( hDC, VERTSIZE ) * 100; ReleaseDC(NULL, hDC); // Calculate the rect in which to draw the metafile based on the // intended size and the current output device resolution // Remember that the intended size is given in 0.01mm units, so // convert those to device units on the target device //pw->PreferredSize.cx = (int)((float)(emh.rclFrame.right - emh.rclFrame.left) * PixelsX / (MMX)); //pw->PreferredSize.cy = (int)((float)(emh.rclFrame.bottom - emh.rclFrame.top) * PixelsY / (MMY)); pw->PreferredSize.cx = ip.MulDivI32((emh.rclFrame.right - emh.rclFrame.left), PixelsX, MMX); pw->PreferredSize.cy = ip.MulDivI32((emh.rclFrame.bottom - emh.rclFrame.top), PixelsY, MMY); _ASSERTE(pw->PreferredSize.cx>0 && pw->PreferredSize.cy>0); if (pw->PreferredSize.cx < 0) pw->PreferredSize.cx = -pw->PreferredSize.cx; if (pw->PreferredSize.cy < 0) pw->PreferredSize.cy = -pw->PreferredSize.cy; } pImageInfo->pImageContext = pw; pImageInfo->nPages = 1; pImageInfo->Flags = 0; pImageInfo->pFormatName = L"WMF"; pImageInfo->pCompression = NULL; pImageInfo->pComments = NULL; return TRUE; }
static HENHMETAFILE ReadEnhMetaFile(const char *szFileName,long *width, long *height) { #pragma pack( push, 2 ) typedef struct { DWORD dwKey; WORD hmf; SMALL_RECT bbox; WORD wInch; DWORD dwReserved; WORD wCheckSum; } APMHEADER, *PAPMHEADER; #pragma pack( pop ) DWORD dwSize; ENHMETAHEADER emfh; HANDLE hFile; HDC hDC; HENHMETAFILE hTemp; LPBYTE pBits; METAFILEPICT mp; HMETAFILE hOld; *width=512; *height=512; hTemp=GetEnhMetaFile(szFileName); if (hTemp != (HENHMETAFILE) NULL) { /* Enhanced metafile. */ GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } hOld=GetMetaFile(szFileName); if (hOld != (HMETAFILE) NULL) { /* 16bit windows metafile. */ dwSize=GetMetaFileBitsEx(hOld,0,NULL); if (dwSize == 0) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } pBits=MagickAllocateMemory(LPBYTE,dwSize); if (pBits == (LPBYTE) NULL) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0) { MagickFreeMemory(pBits); DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the windows metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=1000; mp.yExt=1000; mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp); ReleaseDC(NULL,hDC); DeleteMetaFile(hOld); MagickFreeMemory(pBits); GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } /* Aldus Placeable metafile. */ hFile=CreateFile(szFileName,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE) return(NULL); dwSize=GetFileSize(hFile,NULL); pBits=MagickAllocateMemory(LPBYTE,dwSize); ReadFile(hFile,pBits,dwSize,&dwSize,NULL); CloseHandle(hFile); if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l) { MagickFreeMemory(pBits); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the placable metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left; *width=mp.xExt; mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top; *height=mp.yExt; mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp); ReleaseDC(NULL,hDC); MagickFreeMemory(pBits); return(hTemp); }
/* * clipboard_data_to_bytes - データをバイト列に変換 */ BYTE *clipboard_data_to_bytes(const DATA_INFO *di, DWORD *ret_size) { BYTE *ret = NULL; BYTE *tmp; DWORD i; DWORD size = 0; if (di->data == NULL) { return NULL; } switch (di->format) { case CF_PALETTE: // パレット i = 0; GetObject(di->data, sizeof(WORD), &i); size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * i); if ((ret = mem_calloc(size)) == NULL) { break; } ((LOGPALETTE *)ret)->palVersion = 0x300; ((LOGPALETTE *)ret)->palNumEntries = (WORD)i; GetPaletteEntries(di->data, 0, i, ((LOGPALETTE *)ret)->palPalEntry); break; case CF_DSPBITMAP: case CF_BITMAP: // ビットマップ if ((ret = bitmap_to_dib(di->data, &size)) == NULL) { break; } break; case CF_OWNERDISPLAY: break; case CF_DSPMETAFILEPICT: case CF_METAFILEPICT: // メタファイル if ((tmp = GlobalLock(di->data)) == NULL) { break; } size = GetMetaFileBitsEx(((METAFILEPICT *)tmp)->hMF, 0, NULL); if ((ret = mem_alloc(size + sizeof(METAFILEPICT))) == NULL) { GlobalUnlock(di->data); break; } CopyMemory(ret, tmp, sizeof(METAFILEPICT)); if (GetMetaFileBitsEx(((METAFILEPICT *)tmp)->hMF, size, ret + sizeof(METAFILEPICT)) == 0) { mem_free(&ret); GlobalUnlock(di->data); break; } size += sizeof(METAFILEPICT); GlobalUnlock(di->data); break; case CF_DSPENHMETAFILE: case CF_ENHMETAFILE: // 拡張メタファイル size = GetEnhMetaFileBits(di->data, 0, NULL); if ((ret = mem_alloc(size)) == NULL) { break; } if (GetEnhMetaFileBits(di->data, size, ret) == 0) { mem_free(&ret); break; } break; default: // その他 if ((tmp = GlobalLock(di->data)) == NULL) { break; } size = di->size; if ((ret = mem_alloc(size)) == NULL) { GlobalUnlock(di->data); break; } CopyMemory(ret, tmp, size); GlobalUnlock(di->data); break; } if (ret_size != NULL) { *ret_size = size; } return ret; }
/* * clipboard_copy_data - クリップボードデータのコピーを作成 */ HANDLE clipboard_copy_data(const UINT format, const HANDLE data, DWORD *ret_size) { HANDLE ret = NULL; BYTE *from_mem, *to_mem; LOGPALETTE *lpal; WORD pcnt; if (data == NULL) { return NULL; } switch (format) { case CF_PALETTE: // パレット pcnt = 0; if (GetObject(data, sizeof(WORD), &pcnt) == 0) { return NULL; } if ((lpal = mem_calloc(sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * pcnt))) == NULL) { return NULL; } lpal->palVersion = 0x300; lpal->palNumEntries = pcnt; if (GetPaletteEntries(data, 0, pcnt, lpal->palPalEntry) == 0) { mem_free(&lpal); return NULL; } ret = CreatePalette(lpal); *ret_size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * pcnt); mem_free(&lpal); break; case CF_DSPBITMAP: case CF_BITMAP: // ビットマップ if ((to_mem = bitmap_to_dib(data, ret_size)) == NULL) { return NULL; } ret = dib_to_bitmap(to_mem); mem_free(&to_mem); break; case CF_OWNERDISPLAY: *ret_size = 0; break; case CF_DSPMETAFILEPICT: case CF_METAFILEPICT: // コピー元ロック if ((from_mem = GlobalLock(data)) == NULL) { return NULL; } // メタファイル if ((ret = GlobalAlloc(GHND, sizeof(METAFILEPICT))) == NULL) { GlobalUnlock(data); return NULL; } // コピー先ロック if ((to_mem = GlobalLock(ret)) == NULL) { GlobalFree(ret); GlobalUnlock(data); return NULL; } CopyMemory(to_mem, from_mem, sizeof(METAFILEPICT)); if ((((METAFILEPICT *)to_mem)->hMF = CopyMetaFile(((METAFILEPICT *)from_mem)->hMF, NULL)) != NULL) { *ret_size = sizeof(METAFILEPICT) + GetMetaFileBitsEx(((METAFILEPICT *)to_mem)->hMF, 0, NULL); } // ロック解除 GlobalUnlock(ret); GlobalUnlock(data); break; case CF_DSPENHMETAFILE: case CF_ENHMETAFILE: // 拡張メタファイル if ((ret = CopyEnhMetaFile(data, NULL)) != NULL) { *ret_size = GetEnhMetaFileBits(ret, 0, NULL); } break; default: // その他 // メモリチェック if (IsBadReadPtr(data, 1) == TRUE) { return NULL; } // サイズ取得 if ((*ret_size = GlobalSize(data)) == 0) { return NULL; } // コピー元ロック if ((from_mem = GlobalLock(data)) == NULL) { return NULL; } // コピー先確保 if ((ret = GlobalAlloc(GHND, *ret_size)) == NULL) { GlobalUnlock(data); return NULL; } // コピー先ロック if ((to_mem = GlobalLock(ret)) == NULL) { GlobalFree(ret); GlobalUnlock(data); return NULL; } // コピー CopyMemory(to_mem, from_mem, *ret_size); // ロック解除 GlobalUnlock(ret); GlobalUnlock(data); break; } return ret; }
static PyObject * py_get_clipboard_data(PyObject* self, PyObject* args) { PyObject *ret; // @pyparm int|format|CF_TEXT|Specifies a clipboard format. For a description of // the standard clipboard formats, see Standard Clipboard Formats. // In Unicode builds (ie, python 3k), the default is CF_UNICODETEXT. #ifdef UNICODE int format = CF_UNICODETEXT; #else int format = CF_TEXT; #endif if (!PyArg_ParseTuple(args, "|i:GetClipboardData:", &format)) { return NULL; } if (!IsClipboardFormatAvailable(format)){ PyErr_SetString(PyExc_TypeError, "Specified clipboard format is not available"); return NULL; } HANDLE handle; WCHAR *filename=NULL; PyObject* obfilename = NULL; UINT filecnt=0, fileind=0, filenamesize=0; HDROP hdrop; Py_BEGIN_ALLOW_THREADS; handle = GetClipboardData((UINT)format); Py_END_ALLOW_THREADS; if (!handle) { return ReturnAPIError("GetClipboardData"); } void * cData = NULL; size_t size; DWORD dwordsize; switch (format) { case CF_BITMAP: break; case CF_HDROP: hdrop = (HDROP)GlobalLock(handle); break; case CF_ENHMETAFILE: dwordsize = GetEnhMetaFileBits((HENHMETAFILE)handle, 0, NULL); if (!dwordsize) return ReturnAPIError("GetClipboardData:GetEnhMetafileBits(NULL)"); // allocate a temporary buffer for enhanced metafile cData = malloc(dwordsize); if (cData == NULL) return ReturnAPIError("GetClipboardData:malloc"); // copy enhanced metafile into the temporary buffer if (0 == GetEnhMetaFileBits((HENHMETAFILE)handle, dwordsize, (LPBYTE)cData)) { free(cData); return ReturnAPIError("GetClipboardData:GetEnhMetafileBits"); } size=dwordsize; break; case CF_METAFILEPICT: // @todo CF_METAFILEPICT format returns a pointer to a METAFILEPICT struct which contains the metafile handle, // rather than returning the handle directly. This code currently fails with // error: (6, 'GetClipboardData:GetMetafileBitsEx(NULL)', 'The handle is invalid.') dwordsize = GetMetaFileBitsEx((HMETAFILE)handle, 0, NULL); if (!dwordsize) return ReturnAPIError("GetClipboardData:GetMetafileBitsEx(NULL)"); // allocate a temporary buffer for metafile cData = malloc(dwordsize); if (cData == NULL) return ReturnAPIError("GetClipboardData:malloc"); // copy metafile into the temporary buffer if (0 == GetMetaFileBitsEx((HMETAFILE)handle, dwordsize, cData)) { free(cData); return ReturnAPIError("GetClipboardData:GetMetafileBitsEx"); } size=dwordsize; break; // All other formats simply return the data as a blob. default: cData = GlobalLock(handle); if (!cData) { GlobalUnlock(handle); return ReturnAPIError("GetClipboardData:GlobalLock"); } size = GlobalSize(cData); if (!size) { GlobalUnlock(handle); return ReturnAPIError("GetClipboardData:GlobalSize"); } break; } switch (format) { case CF_BITMAP: ret = PyWinLong_FromHANDLE(handle); break; case CF_HDROP: filecnt = DragQueryFileW(hdrop, 0xFFFFFFFF, NULL, NULL); ret = PyTuple_New(filecnt); if (!ret) return PyErr_NoMemory(); for (fileind=0;fileind<filecnt;fileind++){ filenamesize = DragQueryFileW(hdrop, fileind, NULL, NULL); filename = (WCHAR *)malloc((filenamesize+1)*sizeof(WCHAR)); if (!filename) { Py_DECREF(ret); return PyErr_NoMemory(); } filenamesize = DragQueryFileW(hdrop, fileind, filename, filenamesize+1); obfilename=PyWinObject_FromWCHAR(filename); PyTuple_SetItem(ret,fileind,obfilename); free (filename); } GlobalUnlock(handle); break; case CF_UNICODETEXT: ret = PyUnicode_FromWideChar((wchar_t *)cData, (size / sizeof(wchar_t))-1); GlobalUnlock(handle); break; // For the text formats, strip the null! case CF_TEXT: case CF_OEMTEXT: ret = PyString_FromStringAndSize((char *)cData, size-1); GlobalUnlock(handle); break; default: assert(cData); if (!cData) { ret = Py_None; Py_INCREF(ret); } else ret = PyString_FromStringAndSize((char *)cData, size); GlobalUnlock(handle); break; } return ret; // @comm An application can enumerate the available formats in advance by // using the EnumClipboardFormats function.<nl> // The clipboard controls the handle that the GetClipboardData function // returns, not the application. The application should copy the data // immediately. The application cannot rely on being able to make long-term // use of the handle. The application must not free the handle nor leave it // locked.<nl> // The system performs implicit data format conversions between certain // clipboard formats when an application calls the GetClipboardData function. // For example, if the CF_OEMTEXT format is on the clipboard, a window can // retrieve data in the CF_TEXT format. The format on the clipboard is // converted to the requested format on demand. For more information, see // Synthesized Clipboard Formats. // @pyseeapi GetClipboardData // @pyseeapi Standard Clipboard Formats // @rdesc If the function fails, the standard win32api.error exception // is raised. If the function succeeds, the return value is as // described in the following table: // @flagh Format|Result type // @flag CF_HDROP|A tuple of Unicode filenames. // @flag CF_UNICODETEXT|A unicode object. // @flag CF_OEMTEXT|A string object. // @flag CF_TEXT|A string object. // @flag CF_ENHMETAFILE|A string with binary data obtained from GetEnhMetaFileBits // @flag CF_METAFILEPICT|A string with binary data obtained from GetMetaFileBitsEx (currently broken) // @flag CF_BITMAP|An integer handle to the bitmap. // @flag All other formats|A string with binary data obtained directly from the // global memory referenced by the handle. }
/* %F cdPlay para Clipboard. Interpreta os dados do clipboard, seja metafile ou bitmap. */ static int cdplay(cdCanvas* canvas, int xmin, int xmax, int ymin, int ymax, void *data) { char filename[10240]; HANDLE hFile; DWORD dwSize, nBytesWrite; int err; unsigned char* buffer; (void)data; if (IsClipboardFormatAvailable(CF_TEXT)) { HANDLE Handle; if (!cdStrTmpFileName(filename)) return CD_ERROR; OpenClipboard(NULL); Handle = GetClipboardData(CF_TEXT); if (Handle == NULL) { CloseClipboard(); return CD_ERROR; } buffer = (unsigned char*)GlobalLock(Handle); dwSize = (DWORD)GlobalSize(Handle); hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); WriteFile(hFile, buffer, dwSize, &nBytesWrite, NULL); CloseHandle(hFile); GlobalUnlock(Handle); CloseClipboard(); err = cdCanvasPlay(canvas, CD_METAFILE, xmin, xmax, ymin, ymax, filename); DeleteFile(filename); if (err == CD_OK) return err; } if (IsClipboardFormatAvailable(CF_ENHMETAFILE)) { HENHMETAFILE Handle; if (!cdStrTmpFileName(filename)) return CD_ERROR; OpenClipboard(NULL); Handle = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE); if (Handle == NULL) { CloseClipboard(); return CD_ERROR; } dwSize = GetEnhMetaFileBits(Handle, 0, NULL); buffer = (unsigned char*)malloc(dwSize); GetEnhMetaFileBits(Handle, dwSize, buffer); hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); WriteFile(hFile, buffer, dwSize, &nBytesWrite, NULL); CloseHandle(hFile); free(buffer); CloseClipboard(); err = cdCanvasPlay(canvas, CD_EMF, xmin, xmax, ymin, ymax, filename); DeleteFile(filename); return err; } if (IsClipboardFormatAvailable(CF_METAFILEPICT)) { HANDLE Handle; METAFILEPICT* lpMFP; if (!cdStrTmpFileName(filename)) return CD_ERROR; OpenClipboard(NULL); Handle = GetClipboardData(CF_METAFILEPICT); if (Handle == NULL) { CloseClipboard(); return CD_ERROR; } lpMFP = (METAFILEPICT*) GlobalLock(Handle); dwSize = GetMetaFileBitsEx(lpMFP->hMF, 0, NULL); buffer = (unsigned char*)malloc(dwSize); GetMetaFileBitsEx(lpMFP->hMF, dwSize, buffer); hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); wmfWritePlacebleFile(hFile, buffer, dwSize, lpMFP->mm, lpMFP->xExt, lpMFP->yExt); CloseHandle(hFile); GlobalUnlock(Handle); free(buffer); CloseClipboard(); err = cdCanvasPlay(canvas, CD_WMF, xmin, xmax, ymin, ymax, filename); DeleteFile(filename); return err; } if (IsClipboardFormatAvailable(CF_DIB)) { HANDLE Handle; int size; cdwDIB dib; OpenClipboard(NULL); Handle = GetClipboardData(CF_DIB); if (Handle == NULL) { CloseClipboard(); return CD_ERROR; } cdwDIBReference(&dib, (BYTE*) GlobalLock(Handle), NULL); if (dib.type == -1) { GlobalUnlock(Handle); CloseClipboard(); return CD_ERROR; } if (cdsizecb) { int err; err = cdsizecb(canvas, dib.w, dib.h, dib.w, dib.h); if (err) { GlobalUnlock(Handle); CloseClipboard(); return CD_ERROR; } } size = dib.w*dib.h; if (xmax == 0) xmax = dib.w + xmin - 1; if (ymax == 0) ymax = dib.h + ymin - 1; if (dib.type == 0) { unsigned char *r, *g, *b; r = (unsigned char*)malloc(size); g = (unsigned char*)malloc(size); b = (unsigned char*)malloc(size); cdwDIBDecodeRGB(&dib, r, g, b); cdCanvasPutImageRectRGB(canvas, dib.w, dib.h, r, g, b, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1, 0, 0, 0, 0); free(r); free(g); free(b); } else { unsigned char *index; long *colors; index = (unsigned char*)malloc(size); colors = (long*)malloc(256*sizeof(long)); cdwDIBDecodeMap(&dib, index, colors); cdCanvasPutImageRectMap(canvas, dib.w, dib.h, index, colors, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1, 0, 0, 0, 0); free(index); free(colors); } GlobalUnlock(Handle); CloseClipboard(); return CD_ERROR; } if (IsClipboardFormatAvailable(CF_BITMAP)) { HBITMAP Handle; int size, type; cdwDIB dib; HDC ScreenDC; SIZE sz; OpenClipboard(NULL); Handle = GetClipboardData(CF_BITMAP); if (Handle == NULL) { CloseClipboard(); return CD_ERROR; } GetBitmapDimensionEx(Handle, &sz); ScreenDC = GetDC(NULL); if (GetDeviceCaps(ScreenDC, BITSPIXEL) > 8) type = 0; else type = 1; dib.w = sz.cx; dib.h = sz.cy; dib.type = type; if (cdsizecb) { int err; err = cdsizecb(canvas, dib.w, dib.h, dib.w, dib.h); if (err) { ReleaseDC(NULL, ScreenDC); CloseClipboard(); return CD_ERROR; } } cdwCreateDIB(&dib); GetDIBits(ScreenDC, Handle, 0, sz.cy, dib.bits, dib.bmi, DIB_RGB_COLORS); ReleaseDC(NULL, ScreenDC); size = dib.w*dib.h; if (dib.type == 0) { unsigned char *r, *g, *b; r = (unsigned char*)malloc(size); g = (unsigned char*)malloc(size); b = (unsigned char*)malloc(size); cdwDIBDecodeRGB(&dib, r, g, b); cdCanvasPutImageRectRGB(canvas, dib.w, dib.h, r, g, b, 0, 0, dib.w, dib.h, 0, 0, 0, 0); free(r); free(g); free(b); } else { unsigned char *index; long *colors; index = (unsigned char*)malloc(size); colors = (long*)malloc(256*sizeof(long)); cdwDIBDecodeMap(&dib, index, colors); cdCanvasPutImageRectMap(canvas, dib.w, dib.h, index, colors, 0, 0, dib.w, dib.h, 0, 0, 0, 0); free(index); free(colors); } cdwKillDIB(&dib); CloseClipboard(); return CD_ERROR; } return CD_ERROR; }