385 lines
9.6 KiB
C++
385 lines
9.6 KiB
C++
// Preview.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "MSQSCAN.h"
|
|
#include "Preview.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPreview
|
|
|
|
CPreview::CPreview()
|
|
{
|
|
m_hBitmap = NULL;
|
|
}
|
|
|
|
CPreview::~CPreview()
|
|
{
|
|
}
|
|
|
|
void CPreview::GetSelectionRect(RECT *pRect)
|
|
{
|
|
CopyRect(pRect,&m_RectTracker.m_rect);
|
|
}
|
|
|
|
void CPreview::SetSelectionRect(RECT *pRect)
|
|
{
|
|
CopyRect(&m_RectTracker.m_rect,pRect);
|
|
InvalidateSelectionRect();
|
|
}
|
|
|
|
void CPreview::SetPreviewRect(CRect Rect)
|
|
{
|
|
m_PreviewRect.left = 0;
|
|
m_PreviewRect.top = 0;
|
|
m_PreviewRect.right = Rect.Width();
|
|
m_PreviewRect.bottom = Rect.Height();
|
|
|
|
//
|
|
// set selection rect styles
|
|
//
|
|
|
|
m_RectTracker.m_rect.left = PREVIEW_SELECT_OFFSET;
|
|
m_RectTracker.m_rect.top = PREVIEW_SELECT_OFFSET;
|
|
m_RectTracker.m_rect.right = Rect.Width()-PREVIEW_SELECT_OFFSET;
|
|
m_RectTracker.m_rect.bottom = Rect.Height()-PREVIEW_SELECT_OFFSET;
|
|
|
|
m_RectTracker.m_nStyle = CRectTracker::resizeInside|CRectTracker::dottedLine;
|
|
m_RectTracker.SetClippingWindow(m_RectTracker.m_rect);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CPreview, CWnd)
|
|
//{{AFX_MSG_MAP(CPreview)
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_SETCURSOR()
|
|
ON_WM_PAINT()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPreview message handlers
|
|
|
|
void CPreview::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
m_RectTracker.Track(this,point,FALSE,this);
|
|
InvalidateSelectionRect();
|
|
CWnd::OnLButtonDown(nFlags, point);
|
|
}
|
|
|
|
BOOL CPreview::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
{
|
|
if(m_RectTracker.SetCursor(pWnd,nHitTest))
|
|
return TRUE;
|
|
return CWnd::OnSetCursor(pWnd, nHitTest, message);
|
|
}
|
|
|
|
void CPreview::OnPaint()
|
|
{
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
if(m_hBitmap == NULL) {
|
|
|
|
CRect TrueRect;
|
|
GetWindowRect(TrueRect);
|
|
|
|
//
|
|
// convert to client coords
|
|
//
|
|
|
|
CWnd* pParent = GetParent();
|
|
if(pParent) {
|
|
ScreenToClient(TrueRect);
|
|
|
|
//
|
|
// create a white brush
|
|
//
|
|
|
|
CBrush WhiteBrush;
|
|
WhiteBrush.CreateSolidBrush(RGB(255,255,255));
|
|
|
|
//
|
|
// select white brush, while saving previously selected brush
|
|
//
|
|
|
|
CBrush* pOldBrush = dc.SelectObject(&WhiteBrush);
|
|
|
|
//
|
|
// fill the preview window with white
|
|
//
|
|
|
|
dc.FillRect(TrueRect,&WhiteBrush);
|
|
|
|
//
|
|
// put back the previously selected brush
|
|
//
|
|
|
|
dc.SelectObject(pOldBrush);
|
|
|
|
//
|
|
// destroy the white brush
|
|
//
|
|
|
|
WhiteBrush.DeleteObject();
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// paint preview bitmap
|
|
//
|
|
|
|
PaintHBITMAPToDC();
|
|
}
|
|
|
|
//
|
|
// draw the selection rect, over the image
|
|
//
|
|
|
|
m_RectTracker.Draw(&dc);
|
|
}
|
|
|
|
void CPreview::InvalidateSelectionRect()
|
|
{
|
|
//
|
|
// get parent window
|
|
//
|
|
|
|
CWnd* pParent = GetParent();
|
|
|
|
if(pParent) {
|
|
|
|
//
|
|
// get your window rect
|
|
//
|
|
|
|
CRect TrueRect;
|
|
GetWindowRect(TrueRect);
|
|
|
|
//
|
|
// convert to client coords
|
|
//
|
|
|
|
pParent->ScreenToClient(TrueRect);
|
|
|
|
//
|
|
// invalidate through parent, because we are using the parent's DC to
|
|
// draw images.
|
|
//
|
|
|
|
pParent->InvalidateRect(TrueRect);
|
|
}
|
|
}
|
|
|
|
void CPreview::SetHBITMAP(HBITMAP hBitmap)
|
|
{
|
|
m_hBitmap = hBitmap;
|
|
PaintHBITMAPToDC();
|
|
}
|
|
|
|
void CPreview::PaintHBITMAPToDC()
|
|
{
|
|
//
|
|
// get hdc
|
|
//
|
|
|
|
HDC hMemorydc = NULL;
|
|
HDC hdc = ::GetWindowDC(m_hWnd);
|
|
BITMAP bitmap;
|
|
|
|
if(hdc != NULL){
|
|
|
|
//
|
|
// create a memory dc
|
|
//
|
|
|
|
hMemorydc = ::CreateCompatibleDC(hdc);
|
|
if(hMemorydc != NULL){
|
|
|
|
//
|
|
// select HBITMAP into your hMemorydc
|
|
//
|
|
|
|
if(::GetObject(m_hBitmap,sizeof(BITMAP),(LPSTR)&bitmap) != 0) {
|
|
HGDIOBJ hGDIObj = ::SelectObject(hMemorydc,m_hBitmap);
|
|
|
|
RECT ImageRect;
|
|
ImageRect.top = 0;
|
|
ImageRect.left = 0;
|
|
ImageRect.right = bitmap.bmWidth;
|
|
ImageRect.bottom = bitmap.bmHeight;
|
|
|
|
ScaleBitmapToDC(hdc,hMemorydc,&m_PreviewRect,&ImageRect);
|
|
|
|
} else {
|
|
OutputDebugString(TEXT("Failed GetObject\n"));
|
|
}
|
|
}
|
|
|
|
//
|
|
// delete hMemorydc
|
|
//
|
|
|
|
::DeleteDC(hMemorydc);
|
|
}
|
|
|
|
//
|
|
// delete hdc
|
|
//
|
|
|
|
::ReleaseDC(m_hWnd,hdc);
|
|
}
|
|
|
|
void CPreview::ScreenRectToClientRect(HWND hWnd,LPRECT pRect)
|
|
{
|
|
POINT PtConvert;
|
|
|
|
PtConvert.x = pRect->left;
|
|
PtConvert.y = pRect->top;
|
|
|
|
//
|
|
// convert upper left point
|
|
//
|
|
|
|
::ScreenToClient(hWnd,&PtConvert);
|
|
|
|
pRect->left = PtConvert.x;
|
|
pRect->top = PtConvert.y;
|
|
|
|
PtConvert.x = pRect->right;
|
|
PtConvert.y = pRect->bottom;
|
|
|
|
//
|
|
// convert lower right point
|
|
//
|
|
|
|
::ScreenToClient(hWnd,&PtConvert);
|
|
|
|
pRect->right = PtConvert.x;
|
|
pRect->bottom = PtConvert.y;
|
|
|
|
pRect->bottom-=1;
|
|
pRect->left+=1;
|
|
pRect->right-=1;
|
|
pRect->top+=1;
|
|
}
|
|
|
|
void CPreview::ScaleBitmapToDC(HDC hDC, HDC hDCM, LPRECT lpDCRect, LPRECT lpDIBRect)
|
|
{
|
|
::SetStretchBltMode(hDC, COLORONCOLOR);
|
|
|
|
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
|
|
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
|
|
::BitBlt (hDC, // hDC
|
|
lpDCRect->left, // DestX
|
|
lpDCRect->top, // DestY
|
|
RECTWIDTH(lpDCRect), // nDestWidth
|
|
RECTHEIGHT(lpDCRect), // nDestHeight
|
|
hDCM,
|
|
0,
|
|
0,
|
|
SRCCOPY);
|
|
else {
|
|
StretchBlt(hDC, // hDC
|
|
lpDCRect->left, // DestX
|
|
lpDCRect->top, // DestY
|
|
lpDCRect->right,//ScaledWidth, // nDestWidth
|
|
lpDCRect->bottom,//ScaledHeight, // nDestHeight
|
|
hDCM,
|
|
0, // SrcX
|
|
0, // SrcY
|
|
RECTWIDTH(lpDIBRect), // wSrcWidth
|
|
RECTHEIGHT(lpDIBRect), // wSrcHeight
|
|
SRCCOPY); // dwROP
|
|
}
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRectTrackerEx overridden functions
|
|
|
|
void CRectTrackerEx::AdjustRect( int nHandle, LPRECT lpRect )
|
|
{
|
|
//
|
|
// if clipping rect is empty, do nothing
|
|
//
|
|
|
|
if (!m_rectClippingWindow.IsRectEmpty()) {
|
|
if (nHandle == hitMiddle) {
|
|
|
|
// user is dragging entire selection around...
|
|
// make sure selection rect does not get out of clipping
|
|
// rect
|
|
//
|
|
|
|
CRect rect = lpRect;
|
|
if (rect.right > m_rectClippingWindow.right)
|
|
rect.OffsetRect(m_rectClippingWindow.right - rect.right, 0);
|
|
if (rect.left < m_rectClippingWindow.left)
|
|
rect.OffsetRect(m_rectClippingWindow.left - rect.left, 0);
|
|
if (rect.bottom > m_rectClippingWindow.bottom)
|
|
rect.OffsetRect(0, m_rectClippingWindow.bottom - rect.bottom);
|
|
if (rect.top < m_rectClippingWindow.top)
|
|
rect.OffsetRect(0, m_rectClippingWindow.top - rect.top);
|
|
*lpRect = rect;
|
|
} else {
|
|
|
|
//
|
|
// user is resizing the selection rect
|
|
// make sure selection rect does not extend outside of clipping
|
|
// rect
|
|
//
|
|
|
|
int *px, *py;
|
|
|
|
//
|
|
// get X and Y selection axis
|
|
//
|
|
|
|
GetModifyPointers(nHandle, &px, &py, NULL, NULL);
|
|
|
|
if (px != NULL)
|
|
*px = max(min(m_rectClippingWindow.right, *px), m_rectClippingWindow.left);
|
|
if (py != NULL)
|
|
*py = max(min(m_rectClippingWindow.bottom, *py), m_rectClippingWindow.top);
|
|
|
|
CRect rect = lpRect;
|
|
|
|
//
|
|
// check/adjust X axis
|
|
//
|
|
|
|
if (px != NULL && abs(rect.Width()) < m_sizeMin.cx) {
|
|
if (*px == rect.left)
|
|
rect.left = rect.right;
|
|
else
|
|
rect.right = rect.left;
|
|
}
|
|
|
|
//
|
|
// check/adjust Y axis
|
|
//
|
|
|
|
if (py != NULL && abs(rect.Height()) < m_sizeMin.cy) {
|
|
if (*py == rect.top)
|
|
rect.top = rect.bottom;
|
|
else
|
|
rect.bottom = rect.top;
|
|
}
|
|
|
|
//
|
|
// save the adjusted rectangle
|
|
//
|
|
|
|
*lpRect = rect;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CRectTrackerEx::SetClippingWindow(CRect Rect)
|
|
{
|
|
m_rectClippingWindow = Rect;
|
|
}
|