⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dibview.cpp

📁 <精通Visual C++图像处理编程>源码 对于图像处理很有帮助
💻 CPP
📖 第 1 页 / 共 3 页
字号:

BOOL CDibView::PasteDibFromClipboard()
{
	// get DIB handle from clipboard
	HDIB hNewDIB = NULL;
	if (OpenClipboard())
	{
		if (IsClipboardFormatAvailable(CF_DIB))
			hNewDIB = CopyHandle(GetClipboardData(CF_DIB));

		CloseClipboard();
	}
	if (hNewDIB == NULL)
		return FALSE;

	// if current DIB is empty, use the pasted one as current
	if (m_pDib->IsEmpty())
	{
		// create current DIB
		LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDIB);
		m_pDib->Create(lpDIB);
		GlobalUnlock(hNewDIB);
		GlobalFree(hNewDIB);

		// modify document flags
		CSize sizeTotal(m_pDib->GetWidth(), m_pDib->GetHeight());
		SetScrollSizes(MM_TEXT, sizeTotal);
		CDocument* pDoc = GetDocument();
		OnRealizePal((WPARAM)m_hWnd,0);  // realize the new palette
		pDoc->UpdateAllViews(NULL);
		pDoc->SetModifiedFlag(TRUE);
	}
	else // put it in float DIB window
	{
		// empty current rectangle
		m_rcClip.SetRectEmpty();
		CreateFloatWnd(hNewDIB, CPoint(0, 0));
	}

	return TRUE;
}

BOOL CDibView::PasteBitmapFromClipboard()
{
	// get DIB handle from clipboard
	HBITMAP hNewDDB = NULL;
	HPALETTE hPal = NULL;
	if (OpenClipboard())
	{
		if (IsClipboardFormatAvailable(CF_BITMAP))
			hNewDDB = (HBITMAP)GetClipboardData(CF_BITMAP);
		if (IsClipboardFormatAvailable(CF_PALETTE))
			hPal = (HPALETTE)GetClipboardData(CF_PALETTE);

		CloseClipboard();
	}
	if (hNewDDB == NULL)
		return FALSE;

	// if current DIB is empty, use the pasted one as current
	if (m_pDib->IsEmpty())
	{
		// create current DIB
		m_pDib->Create(hNewDDB, hPal);

		// modify document flags
		CSize sizeTotal(m_pDib->GetWidth(), m_pDib->GetHeight());
		SetScrollSizes(MM_TEXT, sizeTotal);
		CDocument* pDoc = GetDocument();
		OnRealizePal((WPARAM)m_hWnd,0);  // realize the new palette
		pDoc->UpdateAllViews(NULL);
		pDoc->SetModifiedFlag(TRUE);
	}
	else // put it in float DIB window
	{
		// empty current rectangle
		m_rcClip.SetRectEmpty();
		HDIB hDib = BitmapToDIB(hNewDDB, (HPALETTE)m_pDib->m_pPalette->GetSafeHandle());
		HDIB hNewDib = ConvertDIBFormat(hDib, m_pDib->GetBitCount(), (HPALETTE)m_pDib->m_pPalette->GetSafeHandle());
		DestroyDIB(hDib);
		CreateFloatWnd(hNewDib, CPoint(0, 0));
	}

	return TRUE;
}

BOOL CDibView::PastePalFromClipboard()
{
	// egt DIB handle from clipboard
	HPALETTE hPal = NULL;
	if (OpenClipboard())
	{
		if (IsClipboardFormatAvailable(CF_PALETTE))
			hPal = (HPALETTE)GetClipboardData(CF_PALETTE);

		CloseClipboard();
	}
	if (hPal == NULL)
		return FALSE;

	// if current DIB is empty, do nothing
	if (m_pDib->IsEmpty())
		return FALSE;

	// get color bits
	int nEntries;
	WORD wBpp;
	GetObject(hPal, sizeof(int), &nEntries);
	if (nEntries > 16)
		wBpp = 8;
	else if (nEntries > 2)
		wBpp = 4;
	else
		wBpp = 1;

	// convert to new DIB
	HDIB hNewDib = ConvertDIBFormat(m_pDib->m_hDib, wBpp, hPal);
	if (! hNewDib)
		return FALSE;

	m_pDib->Destroy();
	// create current DIB
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib);
	m_pDib->Create(lpDIB);
	GlobalUnlock(hNewDib);
	GlobalFree(hNewDib);
	// modify document flags
	CDocument* pDoc = GetDocument();
	OnRealizePal((WPARAM)m_hWnd,0);  // realize the new palette
	pDoc->UpdateAllViews(NULL);
	pDoc->SetModifiedFlag(TRUE);

	return TRUE;
}

void CDibView::SelectPaste(int nCF)
{
	switch(nCF)
	{
	case CF_DIB:
		PasteDibFromClipboard();
		return;
	case CF_BITMAP:
		PasteBitmapFromClipboard();
		return;
	case CF_PALETTE:
		PastePalFromClipboard();
		return;
	}
}

void CDibView::Paste()
{
	if (! PasteDibFromClipboard())
		if (! PasteBitmapFromClipboard())
			PastePalFromClipboard();
}

void CDibView::OnRealizePal(WPARAM wParam, LPARAM lParam)
{
	ASSERT(wParam != NULL);

	if (m_pDib->IsEmpty())
		return;  // must be a new document

	CPalette* pPal = m_pDib->GetPalette();
	if (pPal != NULL)
	{
		CWnd* pAppFrame = AfxGetApp()->m_pMainWnd;

		CClientDC appDC(pAppFrame);
		// All views but one should be a background palette.
		// wParam contains a handle to the active view, so the SelectPalette
		// bForceBackground flag is FALSE only if wParam == m_hWnd (this view)
		CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd);

		if (oldPalette != NULL)
		{
			UINT nColorsChanged = appDC.RealizePalette();
			if (nColorsChanged > 0)
				GetDocument()->UpdateAllViews(NULL);
			appDC.SelectPalette(oldPalette, TRUE);
		}
		else
		{
			TRACE0("\tSelectPalette failed in CDibView::OnPaletteChanged\n");
		}
	}
}

void CDibView::Rotate(int nAngle)
{
	if (m_pFloatWnd)
	{
		LPBYTE lpDIB = (LPBYTE)GlobalLock(m_pFloatWnd->m_hDibFloat);
		CDib dib;
		if (! dib.Create(lpDIB))
			return;
		GlobalUnlock(m_pFloatWnd->m_hDibFloat);
		switch (nAngle)
		{
		case 90:
			dib.Rotate90();
			break;
		case 180:
			dib.Rotate180();
			break;
		case 270:
			dib.Rotate270();
			break;
		}

		// get float window position
		CRect rcFloat;
		m_pFloatWnd->GetWindowRect(&rcFloat);
		CPoint ptTopLeft = rcFloat.TopLeft();
		ScreenToClient(&ptTopLeft);

		// delete old float window
		DeleteFloatWnd();
		CutSelectedRect();

		// create float window
			// get DIB width and height
		int nWidth  = (int)dib.GetWidth();
		int nHeight = (int)dib.GetHeight();
		CRect rc(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+nWidth, ptTopLeft.y+nHeight);
			// create it
		HDIB hDib = CopyHandle(dib.GetHandle());
		m_pFloatWnd	= new CFloatDibWnd(hDib, rc, this);
	}
	else	// otherwise, copy the entire DIB
	{
		switch (nAngle)
		{
		case 90:
			m_pDib->Rotate90();
			break;
		case 180:
			m_pDib->Rotate180();
			break;
		case 270:
			m_pDib->Rotate270();
			break;
		}
	}
}

void CDibView::Flip(int nDirection)
{
	if (m_pFloatWnd)
	{
		LPBYTE lpDIB = (LPBYTE)GlobalLock(m_pFloatWnd->m_hDibFloat);
		CDib dib;
		if (! dib.Create(lpDIB))
			return;
		GlobalUnlock(m_pFloatWnd->m_hDibFloat);
		switch (nDirection)
		{
		case MD_HORZ:
			dib.FlipHorz();
			break;
		case MD_VERT:
			dib.FlipVert();
			break;
		}

		// get float window position
		CRect rcFloat;
		m_pFloatWnd->GetWindowRect(&rcFloat);
		CPoint ptTopLeft = rcFloat.TopLeft();
		ScreenToClient(&ptTopLeft);

		// delete old float window
		DeleteFloatWnd();
		CutSelectedRect();

		// create float window
			// get DIB width and height
		int nWidth  = (int)dib.GetWidth();
		int nHeight = (int)dib.GetHeight();
		CRect rc(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+nWidth, ptTopLeft.y+nHeight);
			// create it
		HDIB hDib = CopyHandle(dib.GetHandle());
		m_pFloatWnd	= new CFloatDibWnd(hDib, rc, this);
	}
	else	// otherwise, copy the entire DIB
	{
		switch (nDirection)
		{
		case MD_HORZ:
			m_pDib->FlipHorz();
			break;
		case MD_VERT:
			m_pDib->FlipVert();
			break;
		}
	}
}

void CDibView::Zoom(double fRatioX, double fRatioY)
{
	if (m_pFloatWnd)
	{
		LPBYTE lpDIB = (LPBYTE)GlobalLock(m_pFloatWnd->m_hDibFloat);
		CDib dib;
		if (! dib.Create(lpDIB))
			return;
		GlobalUnlock(m_pFloatWnd->m_hDibFloat);
		dib.Zoom(fRatioX, fRatioY);

		// get float window position
		CRect rcFloat;
		m_pFloatWnd->GetWindowRect(&rcFloat);
		CPoint ptTopLeft = rcFloat.TopLeft();
		ScreenToClient(&ptTopLeft);

		// delete old float window
		DeleteFloatWnd();
		CutSelectedRect();

		// create float window
			// get DIB width and height
		int nWidth  = (int)dib.GetWidth();
		int nHeight = (int)dib.GetHeight();
		CRect rc(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+nWidth, ptTopLeft.y+nHeight);
			// create it
		HDIB hDib = CopyHandle(dib.GetHandle());
		m_pFloatWnd	= new CFloatDibWnd(hDib, rc, this);
	}
	else	// otherwise, copy the entire DIB
	{
		m_pDib->Zoom(fRatioX, fRatioY);
	}
}

void CDibView::ChangeImageSize(int nWidth, int nHeight)
{
	if (m_pFloatWnd)
	{
		LPBYTE lpDIB = (LPBYTE)GlobalLock(m_pFloatWnd->m_hDibFloat);
		CDib dib;
		if (! dib.Create(lpDIB))
			return;
		GlobalUnlock(m_pFloatWnd->m_hDibFloat);
		dib.ChangeImageSize(nWidth, nHeight);

		// get float window position
		CRect rcFloat;
		m_pFloatWnd->GetWindowRect(&rcFloat);
		CPoint ptTopLeft = rcFloat.TopLeft();
		ScreenToClient(&ptTopLeft);

		// delete old float window
		DeleteFloatWnd();
		CutSelectedRect();

		// create float window
			// get DIB width and height
		int nWidth  = (int)dib.GetWidth();
		int nHeight = (int)dib.GetHeight();
		CRect rc(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+nWidth, ptTopLeft.y+nHeight);
			// create it
		HDIB hDib = CopyHandle(dib.GetHandle());
		m_pFloatWnd	= new CFloatDibWnd(hDib, rc, this);
	}
	else	// otherwise, copy the entire DIB
	{
		m_pDib->ChangeImageSize(nWidth, nHeight);
	}
}

void CDibView::ChangeCanvasSize(int nWidth, int nHeight, int nPosition)
{
	if (m_pFloatWnd)
	{
		LPBYTE lpDIB = (LPBYTE)GlobalLock(m_pFloatWnd->m_hDibFloat);
		CDib dib;
		if (! dib.Create(lpDIB))
			return;
		GlobalUnlock(m_pFloatWnd->m_hDibFloat);
		dib.ChangeCanvasSize(nWidth, nHeight, nPosition);

		// get float window position
		CRect rcFloat;
		m_pFloatWnd->GetWindowRect(&rcFloat);
		CPoint ptTopLeft = rcFloat.TopLeft();
		ScreenToClient(&ptTopLeft);

		// delete old float window
		DeleteFloatWnd();
		CutSelectedRect();

		// create float window
			// get DIB width and height
		int nWidth  = (int)dib.GetWidth();
		int nHeight = (int)dib.GetHeight();
		CRect rc(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+nWidth, ptTopLeft.y+nHeight);
			// create it
		HDIB hDib = CopyHandle(dib.GetHandle());
		m_pFloatWnd	= new CFloatDibWnd(hDib, rc, this);
	}
	else	// otherwise, copy the entire DIB
	{
		m_pDib->ChangeCanvasSize(nWidth, nHeight, nPosition);
	}
}

void CDibView::Crop()
{
	if (! m_rcClip.IsRectEmpty())
	{
		m_pDib->Crop(m_rcClip);
		DeleteFloatWnd();
		m_rcClip.SetRectEmpty();
	}
}


HBRUSH CDibView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CScrollView::OnCtlColor(pDC, pWnd, nCtlColor);
	
	if (pWnd->m_hWnd == m_EditText.m_hWnd)
		pDC->SetTextColor(m_crPenColor);
	
	// TODO: Return a different brush if the default is not desired
	return hbr;
}

int CDibView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CScrollView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	m_hCursorFreeline = AfxGetApp()->LoadCursor(IDC_CURSORFREELINE);
	m_hCursorFill = AfxGetApp()->LoadCursor(IDC_CURSORFILL);
	m_hCursorCurve = AfxGetApp()->LoadCursor(IDC_CURSORCURVE);
	
	LOGFONT lf;
	HFONT hFont = (HFONT)GetStockObject(SYSTEM_FONT);
	GetObject(hFont, sizeof(LOGFONT), &lf);
	m_pFont = new CFont;
	m_pFont->CreateFontIndirect(&lf);
	
	return 0;
}

BOOL CDibView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	if (m_nDrawType == DT_FREELINE)
	{
		::SetCursor(m_hCursorFreeline);
		return TRUE;
	}
	else if (m_nDrawType == DT_FILL)
	{
		::SetCursor(m_hCursorFill);
		return TRUE;
	}

	return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -