VError VPictureData_GDIPlus_Vector::Save(VBlob* inData,VIndex inOffset,VSize& outSize,_VPictureAccumulator* /*inRecorder*/)const { VError result=VE_UNKNOWN_ERROR; if(fDataProvider) { result=inherited::Save(inData,inOffset,outSize); } else { if(fMetafile) { HENHMETAFILE meta; Gdiplus::Metafile* clone=(Gdiplus::Metafile*)fMetafile->Clone(); meta=clone->GetHENHMETAFILE(); if(meta) { long buffsize=GetEnhMetaFileBits(meta,0,NULL); if(buffsize) { uBYTE* buffer=(uBYTE*)new char[buffsize]; if(buffer) { if(GetEnhMetaFileBits(meta,buffsize,buffer)) { outSize=buffsize; result=inData->PutData(buffer,outSize,inOffset); } delete[] buffer; } } DeleteEnhMetaFile(meta); } delete clone; } } return result; }
BOOL CFemmplotDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // clear out any old metafile; DeleteEnhMetaFile(hMetaPlot); HasBoundingBox=FALSE; HENHMETAFILE hMetaPlotFile = GetEnhMetaFile(lpszPathName); if (hMetaPlotFile!=NULL){ DWORD len =(DWORD) GetEnhMetaFileBits(hMetaPlotFile,NULL,NULL); unsigned char *buff=(unsigned char *) malloc(len); if(GetEnhMetaFileBits(hMetaPlotFile,len,buff)==0) MsgBox("MetaFile not copied"); hMetaPlot=SetEnhMetaFileBits(len,buff); } else MsgBox("Problem opening specified file"); DeleteEnhMetaFile(hMetaPlotFile); // TODO: Add your specialized creation code here return TRUE; }
unsigned char * __RPC_USER HENHMETAFILE_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf) { TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", pBuffer, *phEmf); if (LOWORD(*pFlags) == MSHCTX_INPROC) { if (sizeof(*phEmf) == 8) *(ULONG *)pBuffer = WDT_INPROC64_CALL; else *(ULONG *)pBuffer = WDT_INPROC_CALL; pBuffer += sizeof(ULONG); *(HENHMETAFILE *)pBuffer = *phEmf; pBuffer += sizeof(HENHMETAFILE); } else { *(ULONG *)pBuffer = WDT_REMOTE_CALL; pBuffer += sizeof(ULONG); *(ULONG *)pBuffer = (ULONG)(ULONG_PTR)*phEmf; pBuffer += sizeof(ULONG); if (*phEmf) { UINT emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL); *(ULONG *)pBuffer = emfsize; pBuffer += sizeof(ULONG); *(ULONG *)pBuffer = emfsize; pBuffer += sizeof(ULONG); GetEnhMetaFileBits(*phEmf, emfsize, pBuffer); pBuffer += emfsize; } } return pBuffer; }
/** * Create the clipboard data for a given format. * This assumes that the clipboard is open. * @param HGLOBAL hData the clipboard data. * @param size_t maxMemory the max memory we want to allow to prevent lock-up. * @return ClipboardData*|NULL either the data or NULL if the format does not exist. */ ClipboardData* ClipboardData::FromClipboardEnhmetafile(HGLOBAL hData, size_t maxMemory) { // check the size of the enhenced meta file. // in case it is too large. if (maxMemory > 0 && GetEnhMetaFileBits((HENHMETAFILE)hData, 0, NULL) > maxMemory) { return NULL; } // build the data clipboard so we can restore it. ClipboardData *cf = new ClipboardData(); // copy the meta file. cf->data = CopyEnhMetaFileW((HENHMETAFILE)hData, NULL); cf->dataSize = 0; cf->uFormat = CF_ENHMETAFILE; // return the created filedata. return cf; }
//------------------------------------------------------------------------------ //http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx DWORD WINAPI Scan_clipboard(LPVOID lParam) { //check if local or not :) if (!LOCAL_SCAN) { h_thread_test[(unsigned int)lParam] = 0; check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan return 0; } //db sqlite3 *db = (sqlite3 *)db_scan; if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"BEGIN TRANSACTION;", NULL, NULL, NULL); //lecture du contenu du presse papier et extraction if (OpenClipboard(0)) { char description[MAX_LINE_SIZE], format[DEFAULT_TMP_SIZE], data[MAX_LINE_SIZE],user[NB_USERNAME_SIZE+1]=""; unsigned int session_id = current_session_id; HGLOBAL hMem; //user DWORD s=NB_USERNAME_SIZE; GetUserName(user,&s); int nb_items = CountClipboardFormats(); if (nb_items > 0) { unsigned int uFormat = EnumClipboardFormats(0); #ifdef CMD_LINE_ONLY_NO_DB printf("\"Clipboard\";\"format\";\"code\";\"description\";\"user\";\"session_id\";\"data\";\r\n"); #endif // CMD_LINE_ONLY_NO_DB while (uFormat && start_scan && GetLastError() == ERROR_SUCCESS && --nb_items>0) { //check if ok if (IsClipboardFormatAvailable(uFormat) == FALSE) { uFormat = EnumClipboardFormats(uFormat); continue; } description[0] = 0; data[0]= 0; if (GetClipboardFormatName(uFormat, description, MAX_LINE_SIZE) != 0) { hMem = GetClipboardData(uFormat); if (hMem != NULL) { switch(uFormat) { case CF_TEXT: //format strncpy(format,"CF_TEXT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_BITMAP: //format strncpy(format,"CF_BITMAP",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Bitmap Picture",DEFAULT_TMP_SIZE); //do in bitmap to hexa SaveBitmapToHexaStr((HBITMAP)hMem , data, MAX_LINE_SIZE); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_METAFILEPICT: //format strncpy(format,"CF_METAFILEPICT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Meta-File Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); GlobalUnlock(hMem); break; case CF_SYLK: //format strncpy(format,"CF_SYLK",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Microsoft Symbolic Link (SYLK) data",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%s",(char*)GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_OEMTEXT: //format strncpy(format,"CF_OEMTEXT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text (OEM)",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_DIB: //format strncpy(format,"CF_DIB",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"DIB Bitmap Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_DIF: //format strncpy(format,"CF_DIF",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Software Arts' Data Interchange information",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_TIFF: //format strncpy(format,"CF_TIFF",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Tagged Image File Format (TIFF) Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_PALETTE: //format strncpy(format,"CF_PALETTE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Colour Palette",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_PENDATA: //format strncpy(format,"CF_PENDATA",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Pen Data",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_UNICODETEXT: //format strncpy(format,"CF_UNICODETEXT",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text Unicode",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%S",GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE);h_thread_test[(unsigned int)lParam] = 0; GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_RIFF: //format strncpy(format,"CF_RIFF",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"RIFF Audio data",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_WAVE: //format strncpy(format,"CF_WAVE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Wave File",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_ENHMETAFILE: //format strncpy(format,"CF_ENHMETAFILE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Enhanced Meta-File Picture",DEFAULT_TMP_SIZE); //datas DWORD dwSize = GetEnhMetaFileBits((HENHMETAFILE)hMem, 0, NULL); if (dwSize > 0) { LPBYTE buffer = (LPBYTE)malloc(dwSize); if (buffer != NULL) { if (GetEnhMetaFileBits((HENHMETAFILE)hMem, dwSize, buffer)!=0) { DatatoHexa(buffer, dwSize, data, MAX_LINE_SIZE); } free(buffer); } } addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case CF_HDROP: { //format strncpy(format,"CF_HDROP",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"File List",DEFAULT_TMP_SIZE); HDROP H_DropInfo = (HDROP)hMem; char tmp[MAX_PATH]; DWORD i,nb_path = DragQueryFile(H_DropInfo, 0xFFFFFFFF, tmp, MAX_PATH); long int s2 =MAX_LINE_SIZE; for (i=0;i<nb_path;i++) { //traitement des données ^^ DragQueryFile(H_DropInfo, i, tmp, MAX_PATH); //add if (s2>0) { snprintf(data+strlen(data),s,"%s\r\n",tmp); //strncpy(data+strlen(data),tmp,s); s2-=strlen(data); } } convertStringToSQL(data, MAX_LINE_SIZE); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); } break; case CF_LOCALE: //format strncpy(format,"CF_LOCALE",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Text Locale Identifier",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"0x%X",(unsigned int)GlobalLock(hMem)); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 17: //CF_DIBV5 //format strncpy(format,"CF_DIBV5",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), sizeof(BITMAPV5HEADER), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49155: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"OwnerLink",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49156: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Native Bitmap Picture",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49158: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"FileName",DEFAULT_TMP_SIZE); //datas strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49159: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"FileNameW",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%S",GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; case 49298: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); if (description[0]==0)strncpy(description,"Rich Text Format",DEFAULT_TMP_SIZE); //datas snprintf(data,MAX_LINE_SIZE,"%s",(char*)GlobalLock(hMem)); convertStringToSQL(data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; default: //format strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE); //datas DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE); GlobalUnlock(hMem); addClipboardtoDB(format, uFormat, description, data, user, session_id, db); break; } } } uFormat = EnumClipboardFormats(uFormat); } } CloseClipboard(); } if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"END TRANSACTION;", NULL, NULL, NULL); check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan h_thread_test[(unsigned int)lParam] = 0; return 0; }
// Вызывается ТОЛЬКО в главной нити! void CPluginBackground::UpdateBackground() { if (!mn_BgPluginsCount) return; if (!ghConEmuWndDC || !IsWindow(ghConEmuWndDC)) return; if (mb_ThNeedLoad) { LoadThSet(TRUE/*Мы уже в главной нити*/); } //RECT rcClient; GetClientRect(ghConEmuWndDC, &rcClient); struct PaintBackgroundArg Arg = m_Default; Arg.cbSize = sizeof(struct PaintBackgroundArg); //m_Default.dcSizeX = Arg.dcSizeX = rcClient.right+1; //m_Default.dcSizeY = Arg.dcSizeY = rcClient.bottom+1; m_Default.dcSizeX = Arg.dcSizeX = (m_Default.rcConWorkspace.right-m_Default.rcConWorkspace.left+1)*m_Default.MainFont.nFontCellWidth; m_Default.dcSizeY = Arg.dcSizeY = (m_Default.rcConWorkspace.bottom-m_Default.rcConWorkspace.top+1)*m_Default.MainFont.nFontHeight; // ********************************************************************************** // запомнить данные из m_Default в m_Last, но т.к. там есть указатели - move не катит // ********************************************************************************** //memmove(&m_Last, &m_Default, sizeof(m_Last)); m_Last.MainFont = m_Default.MainFont; memmove(m_Last.crPalette, m_Default.crPalette, sizeof(m_Last.crPalette)); m_Last.dcSizeX = m_Default.dcSizeX; m_Last.dcSizeY = m_Default.dcSizeY; m_Last.rcDcLeft = m_Default.rcDcLeft; m_Last.rcDcRight = m_Default.rcDcRight; m_Last.rcConWorkspace = m_Default.rcConWorkspace; m_Last.conCursor = m_Default.conCursor; m_Last.FarInterfaceSettings.Raw = m_Default.FarInterfaceSettings.Raw; m_Last.FarPanelSettings.Raw = m_Default.FarPanelSettings.Raw; memmove(m_Last.nFarColors, m_Default.nFarColors, sizeof(m_Last.nFarColors)); m_Last.bPanelsAllowed = m_Default.bPanelsAllowed; // struct tag_BkPanelInfo m_Last.LeftPanel.bVisible = m_Default.LeftPanel.bVisible; m_Last.LeftPanel.bFocused = m_Default.LeftPanel.bFocused; m_Last.LeftPanel.bPlugin = m_Default.LeftPanel.bPlugin; m_Last.LeftPanel.rcPanelRect = m_Default.LeftPanel.rcPanelRect; m_Last.RightPanel.bVisible = m_Default.RightPanel.bVisible; m_Last.RightPanel.bFocused = m_Default.RightPanel.bFocused; m_Last.RightPanel.bPlugin = m_Default.RightPanel.bPlugin; m_Last.RightPanel.rcPanelRect = m_Default.RightPanel.rcPanelRect; // строки lstrcpyW(m_Last.LeftPanel.szCurDir, m_Default.LeftPanel.szCurDir); lstrcpyW(m_Last.LeftPanel.szFormat, m_Default.LeftPanel.szFormat); lstrcpyW(m_Last.LeftPanel.szHostFile, m_Default.LeftPanel.szHostFile); lstrcpyW(m_Last.RightPanel.szCurDir, m_Default.RightPanel.szCurDir); lstrcpyW(m_Last.RightPanel.szFormat, m_Default.RightPanel.szFormat); lstrcpyW(m_Last.RightPanel.szHostFile, m_Default.RightPanel.szHostFile); // ********************************************************************************** if (m_Default.dcSizeX < 1 || m_Default.dcSizeY < 1) { _ASSERTE(m_Default.dcSizeX >= 1 && m_Default.dcSizeY >= 1); return; } SetDcPanelRect(&Arg.rcDcLeft, &Arg.LeftPanel, &Arg); SetDcPanelRect(&Arg.rcDcRight, &Arg.RightPanel, &Arg); // gpTabs отстает от реальности. Arg.Place = m_Default.Place; //if (!gpTabs) // Arg.Place = pbp_Panels; //else if (gnCurrentWindowType == WTYPE_EDITOR) // Arg.Place = pbp_Editor; //else if (gnCurrentWindowType == WTYPE_VIEWER) // Arg.Place = pbp_Viewer; //else if (Arg.LeftPanel.bVisible || Arg.RightPanel.bVisible) //{ // _ASSERTE(gnCurrentWindowType == WTYPE_PANELS); // Arg.Place = pbp_Panels; //} BITMAPINFOHEADER bi = {sizeof(BITMAPINFOHEADER)}; bi.biWidth = Arg.dcSizeX; bi.biHeight = Arg.dcSizeY; bi.biPlanes = 1; bi.biBitCount = 32; //-V112 bi.biCompression = BI_RGB; //_ASSERTE(Arg.LeftPanel.bVisible || Arg.RightPanel.bVisible); HDC hScreen = GetDC(NULL); RECT rcMeta = {0,0, Arg.dcSizeX, Arg.dcSizeY}; // (in pixels) int iWidthMM = GetDeviceCaps(hScreen, HORZSIZE); if (iWidthMM <= 0) { _ASSERTE(iWidthMM>0); iWidthMM = 1024; } int iHeightMM = GetDeviceCaps(hScreen, VERTSIZE); if (iHeightMM <= 0) { _ASSERTE(iHeightMM>0); iHeightMM = 768; } int iWidthPels = GetDeviceCaps(hScreen, HORZRES); if (iWidthPels <= 0) { _ASSERTE(iWidthPels>0); iWidthPels = 0; } int iHeightPels = GetDeviceCaps(hScreen, VERTRES); if (iHeightPels <= 0) { _ASSERTE(iHeightPels>0); iHeightPels = 0; } RECT rcMetaMM = {0,0, (rcMeta.right * iWidthMM * 100)/iWidthPels, (rcMeta.bottom * iHeightMM * 100)/iHeightPels}; // (in .01-millimeter units) HDC hdc = NULL; HENHMETAFILE hEmf = NULL; COLORREF* pBits = NULL; HBITMAP hDib = NULL, hOld = NULL; #ifdef CREATE_EMF_TEMP_FILES wchar_t szEmfFile[MAX_PATH] = {}; #endif wchar_t *pszEmfFile = NULL; if (SETBACKGROUND_USE_EMF==1) { #ifdef CREATE_EMF_TEMP_FILES GetTempPath(MAX_PATH-32, szEmfFile); int nLen = lstrlen(szEmfFile); if (*szEmfFile && szEmfFile[nLen-1] != L'\\') { szEmfFile[nLen++] = L'\\'; szEmfFile[nLen] = 0; } _wsprintf(szEmfFile+nLen, SKIPLEN(31) L"CeBack%u.emf", GetCurrentProcessId()); pszEmfFile = szEmfFile; #endif hdc = CreateEnhMetaFile(hScreen, pszEmfFile, &rcMetaMM, L"ConEmu\0Far Background\0\0"); if (!hdc) { _ASSERTE(hdc!=NULL); return; } } else { hdc = CreateCompatibleDC(hScreen); if (!hdc) { _ASSERTE(hdc!=NULL); return; } _ASSERTE(pBits = NULL); hDib = CreateDIBSection(hScreen, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0); } ReleaseDC(NULL, hScreen); hScreen = NULL; Arg.hdc = hdc; if (SETBACKGROUND_USE_EMF==1) { HBRUSH hFillBr = CreateSolidBrush ( #ifdef _DEBUG RGB(128,128,0) #else RGB(0,0,0) #endif ); FillRect(hdc, &rcMeta, hFillBr); DeleteObject(hFillBr); } else { if (!hDib || !pBits) { _ASSERTE(hDib && pBits); if (hDib) DeleteObject(hDib); if (hdc) DeleteDC(hdc); return; } hOld = (HBITMAP)SelectObject(hdc, hDib); // Залить черным - по умолчанию #ifdef _DEBUG memset(pBits, 128, bi.biWidth*bi.biHeight*4); //-V112 #else memset(pBits, 0, bi.biWidth*bi.biHeight*4); #endif } // Painting! int nProcessed = 0; MSectionLock SC; SC.Lock(csBgPlugins, TRUE); DWORD nFromLevel = 0, nNextLevel, nSuggested; DWORD dwDrawnPlaces = Arg.Place; while(true) { nNextLevel = nFromLevel; struct RegisterBackgroundArg *p = mp_BgPlugins; for(int i = 0; i < mn_BgPluginsCount; i++, p++) { if (p->Cmd != rbc_Register || !(p->dwPlaces & Arg.Place) || !(p->PaintConEmuBackground)) continue; // пустая, неактивная в данном контексте, или некорректная ячейка // Слои nSuggested = p->dwSuggestedLevel; if (nSuggested < nFromLevel) { continue; // Этот слой уже обработан } else if (nSuggested > nFromLevel) { // Этот слой нужно будет обработать в следующий раз if ((nNextLevel == nFromLevel) || (nSuggested < nNextLevel)) nNextLevel = nSuggested; continue; } // На уровне 0 (заливающий фон) должен быть только один плагин Arg.dwLevel = (nProcessed == 0) ? 0 : (nFromLevel == 0 && nProcessed) ? 1 : nFromLevel; Arg.lParam = mp_BgPlugins[i].lParam; Arg.dwDrawnPlaces = 0; //mp_BgPlugins[i].PaintConEmuBackground(&Arg); UpdateBackground_Exec(mp_BgPlugins+i, &Arg); // Что плагин покрасил (панели/редактор/вьювер считаются покрашенными по умолчанию) dwDrawnPlaces |= Arg.dwDrawnPlaces; // nProcessed++; } if (nNextLevel == nFromLevel) break; // больше слоев нет nFromLevel = nNextLevel; } SC.Unlock(); // Sending background to GUI! if (nProcessed < 1) { // Ситуация возникает при старте ConEmu, когда панелей "еще нет" //_ASSERTE(nProcessed >= 1); if (mb_BgWasSent) { mb_BgWasSent = FALSE; CESERVER_REQ *pIn = ExecuteNewCmd(CECMD_SETBACKGROUND, sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SETBACKGROUND)); if (pIn) { pIn->Background.nType = 1; pIn->Background.bEnabled = FALSE; pIn->Background.dwDrawnPlaces = 0; CESERVER_REQ *pOut = ExecuteGuiCmd(FarHwnd, pIn, FarHwnd); if (pOut) { ExecuteFreeResult(pOut); } ExecuteFreeResult(pIn); } } } else // есть "отработавшие" плагины, обновить Background! { GdiFlush(); DWORD nBitSize = 0, nBitsError = 0; if (SETBACKGROUND_USE_EMF==1) { hEmf = CloseEnhMetaFile(hdc); hdc = NULL; nBitSize = GetEnhMetaFileBits(hEmf, 0, NULL); if (nBitSize == 0) { dwDrawnPlaces = 0; nBitsError = GetLastError(); _ASSERTE(nBitSize!=0); if (hEmf) { // В случае ошибки - сразу удаляем DeleteEnhMetaFile(hEmf); hEmf = NULL; } } } else { nBitSize = bi.biWidth*bi.biHeight*sizeof(COLORREF); } DWORD nWholeSize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SETBACKGROUND)+nBitSize; //-V103 //-V119 CESERVER_REQ *pIn = ExecuteNewCmd(CECMD_SETBACKGROUND, nWholeSize); if (!pIn) { _ASSERTE(pIn); } else { pIn->Background.nType = 1; pIn->Background.bEnabled = TRUE; pIn->Background.dwDrawnPlaces = dwDrawnPlaces; if (SETBACKGROUND_USE_EMF==1) pIn->Background.bmp.bfType = 0x4645/*EF*/; else pIn->Background.bmp.bfType = 0x4D42/*BM*/; pIn->Background.bmp.bfSize = nBitSize+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //-V119 pIn->Background.bmp.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); //-V119 pIn->Background.bi = bi; if (SETBACKGROUND_USE_EMF==1) { LPBYTE pBits = ((LPBYTE)&pIn->Background)+sizeof(pIn->Background); DWORD nBitsRc = (nBitSize && hEmf) ? GetEnhMetaFileBits(hEmf, nBitSize, pBits) : 0; _ASSERTE(nBitsRc == nBitSize); if (!nBitsRc) { _ASSERTE(nBitsRc!=NULL); // Отключить нафиг ExecutePrepareCmd(&pIn->hdr, CECMD_SETBACKGROUND, nWholeSize-nBitSize); pIn->Background.nType = 1; pIn->Background.bEnabled = FALSE; pIn->Background.dwDrawnPlaces = 0; } } else { memmove(((LPBYTE)&pIn->Background)+sizeof(pIn->Background), pBits, bi.biWidth*bi.biHeight*sizeof(COLORREF)); } CESERVER_REQ *pOut = ExecuteGuiCmd(FarHwnd, pIn, FarHwnd); // Вызывается ТОЛЬКО в главной нити _ASSERTE(GetCurrentThreadId() == gnMainThreadId); if (pOut) { mb_BgWasSent = TRUE; // Сбросим флажок "Ошибка уже была показана" if (pOut->BackgroundRet.nResult == esbr_OK) { mb_BgErrorShown = FALSE; } // Показать ошибку, если есть else if ((pOut->BackgroundRet.nResult > esbr_OK) && (pOut->BackgroundRet.nResult <= esbr_LastErrorNo) && (pOut->BackgroundRet.nResult != esbr_ConEmuInShutdown) && !mb_BgErrorShown) { mb_BgErrorShown = TRUE; Plugin()->ShowMessage(CEBkError_ExecFailed+pOut->BackgroundRet.nResult, 0); } ExecuteFreeResult(pOut); } else if (!mb_BgErrorShown) { mb_BgErrorShown = TRUE; Plugin()->ShowMessage(CEBkError_ExecFailed, 0); } ExecuteFreeResult(pIn); } } if (SETBACKGROUND_USE_EMF == 0) { if (hdc && hOld) SelectObject(hdc, hOld); if (hDib) DeleteObject(hDib); if (hdc) DeleteDC(hdc); } else { if (hdc) { hEmf = CloseEnhMetaFile(hdc); hdc = NULL; } if (hEmf) { DeleteEnhMetaFile(hEmf); hEmf = NULL; } } }
BOOL CDrawDoc::StoreForPrinting(CArchive& ar) { // setting up EMF DC, using default printer as reference HDC hPrt = ((CDrawApp*)AfxGetApp()) -> GetDefaultPrinterIC() ; if (!hPrt) return FALSE; RECT rect={0, 0, GetDeviceCaps(hPrt,HORZSIZE)*100, GetDeviceCaps(hPrt,VERTSIZE)*100}; CDC dc; if (! (dc.m_hDC = CreateEnhMetaFile(hPrt, NULL, &rect, NULL))) return FALSE; dc.SetAttribDC(dc.m_hDC); // recording meta file POSITION pos = GetFirstViewPosition(); CDrawView* pView = (CDrawView*)GetNextView(pos); if (pView == NULL) return FALSE; CDrawView::m_IsRecording = TRUE; pView -> OnPrepareDC(&dc, NULL); Draw(&dc, pView); CDrawView::m_IsRecording = FALSE; HENHMETAFILE hEmf = CloseEnhMetaFile(dc.m_hDC); // storing EMF into archive DWORD size = GetEnhMetaFileBits(hEmf, NULL, NULL); if (size == 0) return FALSE; HGLOBAL hglobal = GlobalAlloc(GMEM_MOVEABLE, size); if (hglobal == NULL) return FALSE; LPBYTE buf = (LPBYTE)GlobalLock(hglobal); if (buf == NULL) return FALSE; if (GetEnhMetaFileBits(hEmf,size,buf) != size) return FALSE; SEPFILEHEADER header; // set EMF size (header) header.dwEmfSize = size; // get text objects count pos = m_objects.GetHeadPosition(); DWORD count=0; while (pos != NULL) { CDrawText* pObj = (CDrawText*)(m_objects.GetNext(pos)); if (pObj->GetLogFontCopy() != NULL) count++; } // set text records (header) header.dwTextRecords = count; // set page size (in logical) (header) header.sizePage = GetSize(); // write header ar.Write(&header,sizeof(SEPFILEHEADER)); // write EMF into archive ar.Write(buf, size); GlobalUnlock(hglobal); GlobalFree(hglobal); DeleteEnhMetaFile(hEmf); // Save text objects for job-info realization and printing // write text records into archive pos = m_objects.GetHeadPosition(); while (pos != NULL) { CDrawText* pObj = (CDrawText*)(m_objects.GetNext(pos)); LOGFONT *plf; if ((plf=pObj->GetLogFontCopy()) != NULL) // is text object { TEXTBOX tbox; tbox.position = pObj->m_position; tbox.color = pObj->m_color; tbox.align = pObj->m_align; tbox.lf = pObj->m_lf; strncpy(tbox.text,pObj->m_text,SEPMAXTEXT); ar.Write(&tbox,sizeof(TEXTBOX)); } } return TRUE; }
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; }
GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) { GpStatus stat; stat = METAFILE_WriteEndOfFile(metafile); metafile->record_graphics = NULL; metafile->hemf = CloseEnhMetaFile(metafile->record_dc); metafile->record_dc = NULL; heap_free(metafile->comment_data); metafile->comment_data = NULL; metafile->comment_data_size = 0; if (stat == Ok) { MetafileHeader header; stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header); if (stat == Ok && metafile->auto_frame && metafile->auto_frame_max.X >= metafile->auto_frame_min.X) { RECTL bounds_rc, gdi_bounds_rc; REAL x_scale = 2540.0 / header.DpiX; REAL y_scale = 2540.0 / header.DpiY; BYTE* buffer; UINT buffer_size; bounds_rc.left = floorf(metafile->auto_frame_min.X * x_scale); bounds_rc.top = floorf(metafile->auto_frame_min.Y * y_scale); bounds_rc.right = ceilf(metafile->auto_frame_max.X * x_scale); bounds_rc.bottom = ceilf(metafile->auto_frame_max.Y * y_scale); gdi_bounds_rc = header.EmfHeader.rclBounds; if (gdi_bounds_rc.right > gdi_bounds_rc.left && gdi_bounds_rc.bottom > gdi_bounds_rc.top) { bounds_rc.left = min(bounds_rc.left, gdi_bounds_rc.left); bounds_rc.top = min(bounds_rc.top, gdi_bounds_rc.top); bounds_rc.right = max(bounds_rc.right, gdi_bounds_rc.right); bounds_rc.bottom = max(bounds_rc.bottom, gdi_bounds_rc.bottom); } buffer_size = GetEnhMetaFileBits(metafile->hemf, 0, NULL); buffer = heap_alloc(buffer_size); if (buffer) { HENHMETAFILE new_hemf; GetEnhMetaFileBits(metafile->hemf, buffer_size, buffer); ((ENHMETAHEADER*)buffer)->rclFrame = bounds_rc; new_hemf = SetEnhMetaFileBits(buffer_size, buffer); if (new_hemf) { DeleteEnhMetaFile(metafile->hemf); metafile->hemf = new_hemf; } else stat = OutOfMemory; heap_free(buffer); } else stat = OutOfMemory; if (stat == Ok) stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header); } if (stat == Ok) { metafile->bounds.X = header.X; metafile->bounds.Y = header.Y; metafile->bounds.Width = header.Width; metafile->bounds.Height = header.Height; } } if (stat == Ok && metafile->record_stream) { BYTE *buffer; UINT buffer_size; buffer_size = GetEnhMetaFileBits(metafile->hemf, 0, NULL); buffer = heap_alloc(buffer_size); if (buffer) { HRESULT hr; GetEnhMetaFileBits(metafile->hemf, buffer_size, buffer); hr = IStream_Write(metafile->record_stream, buffer, buffer_size, NULL); if (FAILED(hr)) stat = hresult_to_status(hr); heap_free(buffer); } else stat = OutOfMemory; } if (metafile->record_stream) { IStream_Release(metafile->record_stream); metafile->record_stream = NULL; } return stat; }
/* * 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; }