|
|
#include "stdafx.h"
#include "global.h"
#include "pbrush.h"
#include "pbrusdoc.h"
#include "pbrusfrm.h"
#include "pbrusvw.h"
#include "minifwnd.h"
#include "bmobject.h"
#include "imgsuprt.h"
#include "imgwnd.h"
#include "imgcolor.h"
#include "imgbrush.h"
#include "imgwell.h"
#include "imgtools.h"
#include "tedit.h"
#include "t_text.h"
#include "t_fhsel.h"
#include "toolbox.h"
#include "props.h"
#include "undo.h"
#include "srvritem.h"
#ifdef _DEBUG
#undef THIS_FILE
static CHAR BASED_CODE THIS_FILE[] = __FILE__; #endif
#include "memtrace.h"
BOOL GetMFDimensions( HANDLE hMF, /* handle to the CF_METAFILEPICT object from clipbrd */ HDC hDC, /* display context */ long *pWidth, /* width of picture in pixels, OUT param */ long *pHeight, /* height of picture in pixels, OUT param */ long *pcXPelsPerMeter, /* horizontal resolution, OUT param */ long *pcYPelsPerMeter, /* vertical resolution, OUT param */ IMG* pImg) ; BOOL PlayMetafileIntoDC( HANDLE hMF, RECT *pRect, HDC hDC) ;
/***************************************************************************/
void CImgWnd::OnDestroyClipboard() { if (m_hPoints) { ::GlobalFree( m_hPoints ); m_hPoints = NULL; } }
/***************************************************************************/
void CImgWnd::CopyBMAndPal(HBITMAP *pBM, CPalette ** ppPal) { IMG* pImg = m_pImg;
CRect copyRect;
if (theImgBrush.m_pImg == NULL) { HideBrush(); copyRect.SetRect(0, 0, pImg->cxWidth, pImg->cyHeight); } else { copyRect = rcDragBrush; copyRect.right -= 1; copyRect.bottom -= 1; }
BOOL bRegion = (CImgTool::GetCurrentID() == IDMB_PICKRGNTOOL);
#ifdef FHSELCLIP
if (bRegion) { if (! m_wClipboardFormat) m_wClipboardFormat = RegisterClipboardFormat( TEXT("MSPaintFreehand") );
if (theImgBrush.m_bFirstDrag) // PickupSelection(); but no way to tell if we do it twice...
PrepareForBrushChange( TRUE, FALSE );
CFreehandSelectTool* pTool = (CFreehandSelectTool*)CImgTool::GetCurrent();
ASSERT( pTool );
if (m_wClipboardFormat && pTool) { CPoint* pptArray; int iEntries; BOOL bData = pTool->CopyPointsToMemArray( &pptArray, &iEntries );
if (bData && iEntries) { HGLOBAL hMem = ::GlobalAlloc( GHND | GMEM_MOVEABLE | GMEM_DDESHARE, iEntries * sizeof( POINT ) + sizeof( short )); if (hMem) { short* pShort = (short*)::GlobalLock( hMem );
*pShort++ = iEntries;
LPPOINT pPts = (LPPOINT)pShort;
for (int iPt = 0; iPt < iEntries; iPt++, pPts++) { pPts->x = pptArray[iPt].x - pTool->m_cRectBounding.left; pPts->y = pptArray[iPt].y - pTool->m_cRectBounding.top; }
::GlobalUnlock( hMem );
if (m_hPoints) { ::GlobalFree( m_hPoints ); m_hPoints = NULL; }
m_hPoints = SetClipboardData( m_wClipboardFormat, hMem ); } else theApp.SetMemoryEmergency();
delete [] pptArray; } } else theApp.SetGdiEmergency(); } #endif // FHSELCLIP
if ( theImgBrush.m_pImg ) { CPalette* ppalOld = SetImgPalette( &theImgBrush.m_dc );
// Copy the selection...
CRect rc( 0, 0, theImgBrush.m_size.cx, theImgBrush.m_size.cy );
*pBM = CopyDC( &theImgBrush.m_dc, &rc );
if (ppalOld) theImgBrush.m_dc.SelectPalette( ppalOld, TRUE ); } else // Copy the whole image...
*pBM = CopyDC( CDC::FromHandle( m_pImg->hDC ), ©Rect );
if (theApp.m_pPalette && (*ppPal=new CPalette)!=NULL) { LOGPALETTE256 logPal;
logPal.palVersion = 0x300; logPal.palNumEntries = (WORD)theApp.m_pPalette->GetPaletteEntries( 0, 256, &logPal.palPalEntry[0]);
if ( logPal.palNumEntries ) { theApp.m_pPalette->GetPaletteEntries( 0, logPal.palNumEntries, &logPal.palPalEntry[0] );
(*ppPal)->CreatePalette( (LPLOGPALETTE)&logPal ); } } }
void CImgWnd::CmdCopy() { if (TextToolProcessed( ID_EDIT_COPY )) { return; }
CBitmapObj* pResObject = new CBitmapObj; if (pResObject) { IMG* pImgStruct = new IMG;
if (pImgStruct) { if (FillBitmapObj(c_pImgWndCur, pResObject, pImgStruct)) { pImgStruct->m_pFirstImgWnd = NULL; pImgStruct->m_pBitmapObj = pResObject;
HDC hDCSave = pImgStruct->hDC;
pImgStruct->hDC = NULL; pImgStruct->hMaskDC = NULL;
pImgStruct->hMaskBitmap = NULL; pImgStruct->hMaskBitmapOld = NULL;
pImgStruct->hBitmap = NULL; pImgStruct->m_pPalette = NULL; CopyBMAndPal(&pImgStruct->hBitmap, &pImgStruct->m_pPalette);
if (pImgStruct->hBitmap) { pImgStruct->hDC = CreateCompatibleDC(hDCSave); if (pImgStruct->hDC) { pImgStruct->hBitmapOld = (HBITMAP)SelectObject( pImgStruct->hDC, pImgStruct->hBitmap); pImgStruct->m_hPalOld = pImgStruct->m_pPalette ? SelectPalette(pImgStruct->hDC, (HPALETTE)pImgStruct->m_pPalette->m_hObject, FALSE) : NULL;
// get a server item suitable to generate the clipboard data
CPBView* pView = (CPBView*) ((CFrameWnd*)AfxGetMainWnd())->GetActiveView(); CPBSrvrItem* pItem = new CPBSrvrItem(pView->GetDocument(), pResObject);
if (pItem) { pItem->CopyToClipboard(FALSE);
delete pItem;
return; } } } } else { // the IMG and all it contains will get cleaned up when
// pResObject is deleted, but only if FillBitmapObj succeeded
delete pImgStruct; } }
delete pResObject; } }
/***************************************************************************/
void CImgWnd::CmdCut() { if (TextToolProcessed( ID_EDIT_CUT )) return;
// BOGUS:
// CmdCopy doesn't just copy -- it can change the state of the selection
// this forces the CmdClear to act in the context of the new state
// save off a flag for CmdClear to special-case like 'first-drag'
BOOL *pFlag; if (theImgBrush.m_pImg && theImgBrush.m_bFirstDrag) { pFlag = &theImgBrush.m_bCuttingFromImage; } else pFlag = NULL;
CmdCopy();
TRY { if (pFlag) *pFlag = TRUE;
CmdClear(); } CATCH_ALL(e) { // don't leave the flag set
if (pFlag) *pFlag = FALSE;
THROW_LAST(); } END_CATCH_ALL
// normal execution path
if (pFlag) *pFlag = FALSE; }
/***************************************************************************/
void CImgWnd::CmdPaste() { if (TextToolProcessed( ID_EDIT_PASTE )) return;
CancelToolMode(FALSE);
CommitSelection(TRUE);
HideBrush(); SetupRubber( m_pImg ); EraseTracker(); theImgBrush.m_pImg = NULL; DrawTracker(); SetUndo( m_pImg );
if (! PasteImageClip()) AfxMessageBox( IDS_ERROR_CLIPBOARD, MB_OK | MB_ICONHAND ); }
/***************************************************************************/
HBITMAP CImgWnd::CopyDC( CDC* pImgDC, CRect* prcClip ) { // BLOCK: copy the image to hStdBitmap for the clipboard
CDC dc; CBitmap bm; CBitmap* pOldStdBitmap; int cxWidth = prcClip->Width(); int cyHeight = prcClip->Height();
if (! dc.CreateCompatibleDC ( pImgDC ) || ! bm.CreateCompatibleBitmap( pImgDC, cxWidth, cyHeight )) { theApp.SetGdiEmergency(); return FALSE; }
pOldStdBitmap = dc.SelectObject( &bm );
CPalette* pOldPalette = SetImgPalette( &dc );
dc.BitBlt( 0, 0, cxWidth, cyHeight, pImgDC, prcClip->left, prcClip->top, SRCCOPY ); dc.SelectObject( pOldStdBitmap );
if (pOldPalette) dc.SelectPalette( pOldPalette, FALSE );
// return the standard format (bitmap) data
return (HBITMAP)bm.Detach(); }
/***************************************************************************/
BOOL CImgWnd::IsPasteAvailable() { BOOL bPasteIsAvailable = FALSE; BOOL bBitmapAvailable = IsClipboardFormatAvailable( CF_BITMAP ); BOOL bDIBAvailable = IsClipboardFormatAvailable( CF_DIB ); BOOL bTextAvailable = IsClipboardFormatAvailable( CF_TEXT ); BOOL bMFAvailable = IsClipboardFormatAvailable( CF_METAFILEPICT );
if (CImgTool::GetCurrentID() == IDMX_TEXTTOOL) { CTextTool* pTextTool = (CTextTool*)CImgTool::GetCurrent();
if (pTextTool != NULL && pTextTool->GetTextEditField() != NULL) bPasteIsAvailable = bTextAvailable; } else { bPasteIsAvailable = bBitmapAvailable || bDIBAvailable || bMFAvailable; }
return bPasteIsAvailable; }
/***************************************************************************/
BOOL CImgWnd::IsSelectionAvailable( void ) { if (CImgTool::GetCurrentID() == IDMX_TEXTTOOL) { CTextTool* pTextTool = (CTextTool*)CImgTool::GetCurrent();
if (pTextTool != NULL && pTextTool->IsKindOf( RUNTIME_CLASS( CTextTool ) )) { CTedit* pTextEdit = pTextTool->GetTextEditField();
if (pTextEdit != NULL && pTextEdit->IsKindOf( RUNTIME_CLASS( CTedit ) )) { DWORD dwSel = pTextEdit->GetEditWindow()->GetSel(); BOOL bReturn = (HIWORD( dwSel) != LOWORD( dwSel ));
if (! bReturn) bReturn = (pTextEdit->GetEditWindow()->GetWindowTextLength() != (int)LOWORD( dwSel ));
return bReturn; } } }
if (CImgTool::GetCurrentID() == IDMB_PICKTOOL || CImgTool::GetCurrentID() == IDMB_PICKRGNTOOL) { return (theImgBrush.m_pImg != NULL && ! g_bCustomBrush); } return FALSE; }
/***************************************************************************/
int PASCAL CheckPastedSize(int nWidth, int nHeight, IMG* pImg) { int nRet = IDNO;
// If the image is a bitmap and the bitmap in the clipboard is larger,
// then give the suer the option2 of growing the image...
if (nWidth > pImg->cxWidth || nHeight > pImg->cyHeight) { CSize size( max(nWidth, pImg->cxWidth), max(nHeight, pImg->cyHeight) );
theUndo.BeginUndo( TEXT("Resize Bitmap") ); VERIFY( pImg->m_pBitmapObj->SetSizeProp( P_Size, size ) );
theUndo.EndUndo();
// PSS says users don't want to see this dialog
#if 0
// WARNING!!! MB_SYSTEMMODAL is _necessary_. No message boxes should
// be run while the clipboard is opened. Loss of focus to other apps
// can be disasterous! The clipboard will be hung or if the clipboard
// is closed, the contents could be changed by another app.
nRet = AfxMessageBox( IDS_ENLAGEBITMAPFORCLIP, MB_YESNOCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL ); switch (nRet) { case IDYES: { CSize size( max(nWidth, pImg->cxWidth), max(nHeight, pImg->cyHeight) );
theUndo.BeginUndo( TEXT("Resize Bitmap") ); VERIFY( pImg->m_pBitmapObj->SetSizeProp( P_Size, size ) );
theUndo.EndUndo(); } break; } #endif
}
return(nRet); }
struct CStgMedium : public STGMEDIUM { CStgMedium() { ZeroMemory(this, sizeof(*this)); }
~CStgMedium() { ReleaseStgMedium(this); } };
HGLOBAL _GetClipboardData (CLIPFORMAT cf, TYMED tymed, STGMEDIUM *pMedium) { IDataObject *pdo = NULL; HANDLE hRet = NULL;
if (SUCCEEDED(OleGetClipboard (&pdo))) { FORMATETC fmt = { 0 };
fmt.cfFormat = cf; fmt.lindex = -1; fmt.tymed = tymed; fmt.dwAspect = DVASPECT_CONTENT;
pMedium->tymed = tymed;
if (SUCCEEDED(pdo->GetData (&fmt, pMedium))) { hRet = pMedium->hGlobal; } else { ReleaseStgMedium(pMedium); }
pdo->Release (); } else { TRACE( TEXT("Cannot open clipboard!\n") ); }
return hRet; }
BOOL CImgWnd::PasteImageClip() { CWaitCursor wait; /////////////////////////////////////////////////////////////////////////
// Find out what format is available on the clipboard. if it is
// A. CF_BITMAP only - Set the mask bits opaque and blt the bitmap
// into ICimageDC
// In both cases, if the destination bitmap differs in size from
// source bitmap, user is asked if he/she wants the src bitmap
// stretched/clipped to new size
/////////////////////////////////////////////////////////////////////////
if (! m_wClipboardFormat) m_wClipboardFormat = (WORD)RegisterClipboardFormat( TEXT("MSPaintFreehand") );
// Enumerate the cliboard contents to determine what is available.
// If a CF_BITMAP is seen, set a flag and proceed. If a SDKPAINT
// private format is seen, stop looking further
BOOL bBitmapAvailable = FALSE; #ifdef FHSELCLIP
BOOL bPrivateAvailable = FALSE; #endif // FHSELCLIP
BOOL bPaletteAvailable = FALSE; BOOL bDIBAvailable = FALSE; BOOL bMFAvailable = FALSE; WORD wClipFmt = 0;
BITMAP bmData; LONG cXPelsPerMeter = 0; LONG cYPelsPerMeter = 0; BOOL bResizedBitmap = FALSE; CPalette* ppalClipboard = NULL; CBitmap* pbmClipboard = NULL; LPSTR lpDib = NULL; HPALETTE hPal = NULL; HBITMAP hBitmap = NULL; HGLOBAL hDIB = NULL; HGLOBAL hMF = NULL;
CStgMedium stgMedium;
BOOL bGotClip = FALSE;
hPal = (HPALETTE)_GetClipboardData( CF_PALETTE, TYMED_GDI, &stgMedium ); if (hPal) { bPaletteAvailable = TRUE; ppalClipboard = CPalette::FromHandle( hPal );
ReleaseStgMedium(&stgMedium); }
if (!bGotClip) { hDIB = (HGLOBAL)_GetClipboardData( CF_DIB, TYMED_HGLOBAL, &stgMedium );
if (hDIB) { lpDib = (LPSTR)::GlobalLock( hDIB );
if (lpDib) { bmData.bmWidth = DIBWidth ( lpDib ); bmData.bmHeight = DIBHeight( lpDib );
if (bmData.bmWidth && bmData.bmHeight) { bDIBAvailable = TRUE; bPaletteAvailable = FALSE;
PBITMAPINFOHEADER pbmih = (PBITMAPINFOHEADER) lpDib;
if (pbmih->biSize >= sizeof(BITMAPINFOHEADER)) { cXPelsPerMeter = pbmih->biXPelsPerMeter; cYPelsPerMeter = pbmih->biYPelsPerMeter; } } } } #ifdef _DEBUG
TRACE1( "Loaded the DIB %s.\n", (bDIBAvailable? TEXT("Yes"): TEXT("No")) ); #endif
bGotClip = bDIBAvailable; }
if (!bGotClip) { hBitmap = (HBITMAP)_GetClipboardData( CF_BITMAP, TYMED_GDI, &stgMedium );
if (hBitmap) { pbmClipboard = CBitmap::FromHandle( hBitmap );
if (pbmClipboard->GetObject( sizeof( BITMAP ), &bmData )) { bBitmapAvailable = TRUE;
DIBSECTION ds;
if (pbmClipboard->GetObject( sizeof( ds ), &ds )) { cXPelsPerMeter = ds.dsBmih.biXPelsPerMeter; cYPelsPerMeter = ds.dsBmih.biYPelsPerMeter; }
if (bPaletteAvailable) { if (!ppalClipboard) bBitmapAvailable = FALSE; } } }
#ifdef _DEBUG
TRACE1( "Loaded the Bitmap %s.\n", (bBitmapAvailable? TEXT("Yes"): TEXT("No")) ); #endif
bGotClip = bBitmapAvailable; }
if (!bGotClip) { hMF = (HGLOBAL)_GetClipboardData(CF_METAFILEPICT, TYMED_MFPICT, &stgMedium); if (hMF) { CDC dcMF;
if (dcMF.CreateCompatibleDC( NULL )) { if (GetMFDimensions(hMF, dcMF.m_hDC, &bmData.bmWidth, &bmData.bmHeight, &cXPelsPerMeter, &cYPelsPerMeter, m_pImg)) { bMFAvailable = TRUE; } } }
bGotClip = bMFAvailable; }
if (!bGotClip) { return FALSE; }
switch (CheckPastedSize(bmData.bmWidth, bmData.bmHeight, m_pImg)) { default: return TRUE;
case IDYES: bResizedBitmap = TRUE; break;
case IDNO: break; }
CDC stdDC; BOOL bOkay = FALSE; CBitmap* pbmOld = NULL; CPalette* ppalOld = NULL;
if (bBitmapAvailable) { CBitmap bmClipboard; CBitmap* pbmOldCopy = NULL; CPalette* ppalOldCopy = NULL; CDC* pdcCopy = NULL;
if (! stdDC.CreateCompatibleDC( NULL )) { theApp.SetGdiEmergency(); goto LReturn; }
pbmOld = stdDC.SelectObject( pbmClipboard );
if (! pbmOld) { theApp.SetGdiEmergency(); goto LReturn; }
if (ppalClipboard) { ppalOld = stdDC.SelectPalette( ppalClipboard, FALSE ); stdDC.RealizePalette(); }
// duplicate the bitmap
if (! bmClipboard.CreateBitmap( bmData.bmWidth, bmData.bmHeight, bmData.bmPlanes, bmData.bmBitsPixel, NULL )) { theApp.SetMemoryEmergency(); goto LReturn; }
pdcCopy = new CDC;
if (pdcCopy == NULL) { theApp.SetMemoryEmergency(); goto LReturn; }
if (! pdcCopy->CreateCompatibleDC( NULL )) { delete pdcCopy; theApp.SetGdiEmergency(); goto LReturn; }
pbmOldCopy = pdcCopy->SelectObject( &bmClipboard );
if (ppalClipboard) { ppalOldCopy = pdcCopy->SelectPalette( ppalClipboard, FALSE ); pdcCopy->RealizePalette(); }
pdcCopy->BitBlt( 0, 0, bmData.bmWidth, bmData.bmHeight, &stdDC, 0, 0, SRCCOPY );
if (ppalOldCopy) pdcCopy->SelectPalette( ppalOldCopy, FALSE );
pdcCopy->SelectObject( pbmOldCopy ); delete pdcCopy;
stdDC.SelectObject( &bmClipboard );
// Unload the bitmap
stdDC.SelectObject( pbmOld ); pbmOld = NULL;
if (ppalOld) { stdDC.SelectPalette( ppalOld, FALSE ); ppalOld = NULL; }
// if we still do not know the image resolution, use the display resolution
if (cXPelsPerMeter == 0 && cYPelsPerMeter == 0) { cXPelsPerMeter = MulDiv(::GetDeviceCaps(stdDC, LOGPIXELSX),10000, 254); cYPelsPerMeter = MulDiv(::GetDeviceCaps(stdDC, LOGPIXELSY),10000, 254); }
stdDC.DeleteDC(); // Now we convert our nice DDB to a DIB and back so we can
// convert color bitmaps to monochrome nicely and deal with
// palette differences...
DWORD dwSize;
lpDib = (LPSTR) DibFromBitmap( (HBITMAP)bmClipboard.GetSafeHandle(), BI_RGB, 0, ppalClipboard, NULL, dwSize, cXPelsPerMeter, cYPelsPerMeter ); }
if (bMFAvailable) { CDC dcMF;
if (dcMF.CreateCompatibleDC(CDC::FromHandle(m_pImg->hDC))) { CBitmap bmMF;
if (bmMF.CreateCompatibleBitmap(CDC::FromHandle(m_pImg->hDC), bmData.bmWidth, bmData.bmHeight)) { dcMF.SelectObject(&bmMF); //not needed for DIBSection!!!
if (ppalClipboard) { dcMF.SelectPalette(ppalClipboard, FALSE); }
CRect rc(0, 0, bmData.bmWidth, bmData.bmHeight);
PlayMetafileIntoDC(hMF, &rc, dcMF.m_hDC);
// Select out the bitmap and palette
dcMF.DeleteDC();
DWORD dwSize;
lpDib = (LPSTR) DibFromBitmap( (HBITMAP)bmMF.m_hObject, BI_RGB, 0, ppalClipboard, NULL, dwSize, cXPelsPerMeter, cYPelsPerMeter ); } } }
if (lpDib) { CPalette* ppalDib = CreateDIBPalette( lpDib );
ppalDib = FixupDibPalette( lpDib, ppalDib );
HBITMAP hbmDib = DIBToBitmap( lpDib, theApp.m_pPalette, m_pImg->hDC );
if (bDIBAvailable) ::GlobalUnlock( hDIB ); else FreeDib( lpDib );
if (hbmDib != NULL && stdDC.CreateCompatibleDC( CDC::FromHandle( m_pImg->hDC ) )) { CRect rtBrush( 0, 0, bmData.bmWidth, bmData.bmHeight ); BOOL bBrushMade = FALSE; CBitmap bmDib;
bmDib.Attach( hbmDib );
pbmOld = stdDC.SelectObject( &bmDib );
if (m_pImg->m_pPalette) { ppalOld = stdDC.SelectPalette( m_pImg->m_pPalette, FALSE ); stdDC.RealizePalette(); }
#ifdef FHSELCLIP
if (bPrivateAvailable) { HGLOBAL hPts = (HGLOBAL)_GetClipboardData( m_wClipboardFormat );
if (hPts) { short* lpShort = (short*)::GlobalLock( hPts );
if (lpShort) { BOOL bError = FALSE; int iEntries = *lpShort++; LPPOINT lpPts = (LPPOINT)lpShort;
CImgTool::Select( IDMB_PICKRGNTOOL ); CFreehandSelectTool* pTool = (CFreehandSelectTool*)CImgTool::GetCurrent();
if (pTool) { if (pTool->CreatePolyRegion( GetZoom(), lpPts, iEntries ) && MakeBrush( stdDC.m_hDC, rtBrush )) { bBrushMade = TRUE; } } ::GlobalUnlock( hPts ); } } } #endif // FHSELCLIP
if (! bBrushMade) { if (CImgTool::GetCurrentID() != IDMB_PICKTOOL) CImgTool::Select( IDMB_PICKTOOL );
bBrushMade = MakeBrush( stdDC.m_hDC, rtBrush ); }
if (bBrushMade) { // We have to "move" the brush so it appears...
CRect rect( 0, 0, theImgBrush.m_rcSelection.Width(), theImgBrush.m_rcSelection.Height() );
if (! bResizedBitmap) { // Move the brush so that it is in the upper-left corner of
// the view (in case it's scrolled)...
rect.OffsetRect( -m_xScroll, -m_yScroll ); } MoveBrush( rect );
DirtyImg( m_pImg );
theImgBrush.m_bFirstDrag = FALSE;
bOkay = TRUE; } else { TRACE( TEXT("Paste: MakeBrush failed!\n") ); } if (ppalOld) { ppalOld = stdDC.SelectPalette( ppalOld, FALSE ); ppalOld = NULL; }
stdDC.SelectObject( pbmOld ); pbmOld = NULL; bmDib.Detach(); }
if (hbmDib != NULL) ::DeleteObject( hbmDib );
if (ppalDib != NULL) delete ppalDib; } LReturn: if (pbmOld != NULL) stdDC.SelectObject( pbmOld );
if (ppalOld != NULL) stdDC.SelectPalette( ppalOld, FALSE );
return bOkay; }
/***************************************************************************/ /* very similar to PasteImageClip, but this will paste into an existing */ /* selection (theImgBrush), resizing it if necessary, and not moving it */ /***************************************************************************/
BOOL CImgWnd::PasteImageFile( LPSTR lpDib ) { CDC stdDC; CRect cRectSelection = theImgBrush.m_rcSelection; BOOL bOkay = FALSE;
if (lpDib == NULL) return bOkay;
int iWidth = (int)DIBWidth ( lpDib ); int iHeight = (int)DIBHeight( lpDib );
if (CImgTool::GetCurrentID()==IDMB_PICKTOOL && theImgBrush.m_bFirstDrag) { if (iWidth < theImgBrush.m_size.cx) { cRectSelection.right = cRectSelection.left + iWidth - 1; } if (iHeight < theImgBrush.m_size.cy) { cRectSelection.bottom = cRectSelection.top + iHeight - 1; }
// If the image is a bitmap and the bitmap in the clipboard is larger,
// then give the user the option of growing the image...
if (iWidth > theImgBrush.m_size.cx || iHeight > theImgBrush.m_size.cy) { cRectSelection.right = cRectSelection.left + iWidth - 1; cRectSelection.bottom = cRectSelection.top + iHeight - 1;
// PSS says users don't want to see this dialog
#if 0
switch (AfxMessageBox( IDS_ENLAGEBITMAPFORCLIP, MB_YESNOCANCEL | MB_ICONQUESTION )) { default: return bOkay; break;
case IDYES: cRectSelection.right = cRectSelection.left + iWidth - 1; cRectSelection.bottom = cRectSelection.top + iHeight - 1; break;
case IDNO: break; } #endif
} } else { int xPos = -m_xScroll; int yPos = -m_yScroll;
switch (CheckPastedSize(iWidth, iHeight, m_pImg)) { case IDYES: xPos = yPos = 0; break;
case IDNO: break;
default: return(bOkay); }
CImgTool::Select(IDMB_PICKTOOL); cRectSelection = CRect(xPos, yPos, xPos+iWidth, yPos+iHeight); }
MakeBrush( m_pImg->hDC, cRectSelection ); // MakeBrush sets this
theImgBrush.m_bFirstDrag = FALSE;
if (! stdDC.CreateCompatibleDC( CDC::FromHandle( m_pImg->hDC ) )) { theApp.SetGdiEmergency(); return bOkay; }
CPalette* ppalDib = CreateDIBPalette( lpDib );
ppalDib = FixupDibPalette( lpDib, ppalDib );
HBITMAP hbmDib = DIBToBitmap( lpDib, theApp.m_pPalette, m_pImg->hDC );
SetUndo( m_pImg );
if (hbmDib != NULL) { CBitmap bmDib; CPalette* ppalOld = NULL; CBitmap* pbmOld = NULL;
bmDib.Attach( hbmDib );
pbmOld = stdDC.SelectObject( &bmDib );
if (m_pImg->m_pPalette) { ppalOld = stdDC.SelectPalette( m_pImg->m_pPalette, FALSE ); stdDC.RealizePalette(); }
if (MakeBrush( stdDC.m_hDC, CRect( CPoint( 0, 0 ), cRectSelection.Size() ) )) { theImgBrush.m_bFirstDrag = FALSE;
// We have to "move" the brush so it appears...
MoveBrush( cRectSelection );
DirtyImg( m_pImg );
bOkay = TRUE; } else { TRACE( TEXT("Paste: MakeBrush failed!\n") ); }
if (ppalOld != NULL) { ppalOld = stdDC.SelectPalette( ppalOld, FALSE ); }
stdDC.SelectObject( pbmOld ); bmDib.Detach();
::DeleteObject( hbmDib ); }
if (ppalDib != NULL) delete ppalDib;
return bOkay; }
/***************************************************************************/ // Stolen from PBrush
//
/****************************Module*Header******************************\
* Module Name: metafile.c * * Routines to paste a metafile as a bitmap. * * Copyright (c) 1987 - 1991 Microsoft Corporation * \***********************************************************************/
/* Computes dimensions of a metafile picture in pixels */ BOOL GetMFDimensions( HANDLE hMF, /* handle to the CF_METAFILEPICT object from clipbrd */ HDC hDC, /* display context */ long *pWidth, /* width of picture in pixels, OUT param */ long *pHeight, /* height of picture in pixels, OUT param */ long *pcXPelsPerMeter, /* horizontal resolution, OUT param */ long *pcYPelsPerMeter, /* vertical resolution, OUT param */ IMG* pImg) { METAFILEPICT FAR *lpMfp, Picture; int MapModeOld=0; RECT Rect; long xScale, yScale, Scale; int hRes, vRes; /* horz and vert resolution, in pixels */ int hSize, vSize; /* horz and vert size, in mm */ int fResult = FALSE;
if (!hMF || !(lpMfp = (METAFILEPICT FAR *)GlobalLock(hMF))) return FALSE; /* copy metafile picture hdr */ Picture = *lpMfp; GlobalUnlock(hMF);
/* Do not modify given DC's attributes */ SaveDC(hDC);
/* set the mapping mode */ MapModeOld = SetMapMode(hDC, Picture.mm); if (Picture.mm != MM_ISOTROPIC && Picture.mm != MM_ANISOTROPIC) { /* For modes other than ISOTROPIC and ANISOTROPIC the picture
* dimensions are given in logical units. /* Convert logical units to pixels. */ Rect.left = 0; Rect.right = Picture.xExt; Rect.top = 0; Rect.bottom = Picture.yExt; if (!LPtoDP(hDC, (LPPOINT)&Rect, 2)) goto Error; *pWidth = Rect.right - Rect.left + 1; *pHeight = Rect.bottom - Rect.top + 1; fResult = TRUE; } else /* ISOTROPIC or ANISOTROPIC mode,
* using the xExt and yExt, determine pixel width and height of * the image */ { hRes = GetDeviceCaps(hDC, HORZRES); vRes = GetDeviceCaps(hDC, VERTRES); hSize = GetDeviceCaps(hDC, HORZSIZE); vSize = GetDeviceCaps(hDC, VERTSIZE); *pcXPelsPerMeter = hRes * 1000 / hSize; *pcYPelsPerMeter = vRes * 1000 / vSize; if (Picture.xExt == 0) /* assume default size, aspect ratio */ { *pWidth = pImg->cxWidth; *pHeight = pImg->cyHeight; } else if (Picture.xExt > 0) /* use suggested size in HIMETRIC units */ { // convert suggested extents(in .01 mm units) for picture to pixel units.
// xPixelsPermm = hRes/hSize;, yPixelsPermm = vRes/vSize;
// Use Pixels Per logical unit.
// *pWidth = Picture.xExt*xPixelsPermm/100;
// *pHeight = Picture.yExt*yPixelsPermm/100;
*pWidth = ((long)Picture.xExt * hRes/hSize/100); *pHeight = ((long)Picture.yExt * vRes/vSize/100); } else if (Picture.xExt < 0) /* use suggested aspect ratio, default size */ { // 1 log unit = .01 mm.
// (# of log units in imageWid pixels)/xExt;
xScale = 100L * (long) pImg->cxWidth * hSize/hRes/-Picture.xExt; // (# of log units in imageHgt pixels)/yExt;
yScale = 100L * (long) pImg->cyHeight * vSize/vRes/-Picture.yExt; // choose the minimum to accomodate the entire image
Scale = min(xScale, yScale); // use scaled Pixels Per log unit.
*pWidth = ((long)-Picture.xExt * Scale * hRes/hSize / 100); *pHeight = ((long)-Picture.yExt * Scale * vRes/vSize / 100); } fResult = TRUE; }
Error: if (MapModeOld) SetMapMode(hDC, MapModeOld); /* select the old mapping mode */ RestoreDC(hDC, -1); return fResult; }
BOOL PlayMetafileIntoDC( HANDLE hMF, RECT *pRect, HDC hDC) { HBRUSH hbrBackground; METAFILEPICT FAR *lpMfp;
if (!(lpMfp = (METAFILEPICT FAR *)GlobalLock(hMF))) return FALSE;
SaveDC(hDC);
/* Setup background color for the bitmap */ hbrBackground = CreateSolidBrush(crRight);
if (hbrBackground) { FillRect(hDC, pRect, hbrBackground); DeleteObject(hbrBackground); }
SetMapMode(hDC, lpMfp->mm); if (lpMfp->mm == MM_ISOTROPIC || lpMfp->mm == MM_ANISOTROPIC) SetViewportExtEx(hDC, pRect->right-pRect->left, pRect->bottom-pRect->top, NULL); PlayMetaFile(hDC, lpMfp->hMF); GlobalUnlock(hMF); RestoreDC(hDC, -1); return TRUE; }
|