// ImageViewer.cpp : ʵÏÖÎļþ¡£ // #include "stdafx.h" #include "ImageViewer.h" IMPLEMENT_DYNAMIC(CImageViewer, CWnd) CImageViewer::CImageViewer(CWnd* pParentWnd) { CoInitialize(0); HRESULT hr = S_OK; // create wic factory hr = ::CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pWICFactory)); if (hr!=S_OK) { } // create d2d factory hr = ::D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory); if (hr!=S_OK) { } m_pWICBitmap = nullptr; m_pWICFormatConverter = nullptr; m_pD2DRenderTarget = nullptr; m_pD2DBitmap = nullptr; m_nWicBitmapWidthStep = 0; m_nWicBitmapHeight = 0; m_nWicBitmapChannels = 0; m_rtViewRect = CRect(0,0,0,0); m_rtOrgViewRect = CRect(0,0,0,0); m_pParentWnd = pParentWnd; m_strViewName = _T(""); // scroll pos m_nVScroll = 0; m_nHScroll = 0; // max scroll pos m_nMaxVScroll = 0; m_nMaxHScroll = 0; // image draw m_nViewType = ViewScale_Fit; m_nScaleWidth = 0; m_nScaleHeight = 0; m_dWidthScale = 1.0; m_dHeightScale = 1.0; // draw view name m_bDrawViewName = FALSE; m_strViewName = _T(""); // draw roi m_bDrawRoi = FALSE; m_rtRoiRect.Reset(); // draw object m_bDrawObject = FALSE; m_listDrawObject.clear(); // d2d1 cs m_pD2DCriticalSection = new CCriticalSection(); } CImageViewer::~CImageViewer() { SafeDelete(m_pD2DCriticalSection); SafeRelease(m_pD2DBitmap); SafeRelease(m_pWICBitmap); SafeRelease(m_pWICFormatConverter); SafeRelease(m_pD2DRenderTarget); SafeRelease(m_pD2DFactory); SafeRelease(m_pWICFactory); m_listDrawObject.clear(); CoUninitialize(); } BEGIN_MESSAGE_MAP(CImageViewer, CWnd) ON_WM_PAINT() ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_CREATE() ON_WM_SIZE() ON_WM_CREATE() END_MESSAGE_MAP() // CImageViewer ÏûÏ¢´¦ÀíÆ÷¡£ BOOL CImageViewer::CreateRenderTarget(const CRect& rtRect) { CSingleLock myLock(m_pD2DCriticalSection); myLock.Lock(); BOOL bSame = (rtRect == m_rtViewRect); if (bSame && (m_pD2DRenderTarget!=nullptr)) return TRUE; m_rtViewRect = rtRect; // create hwnd render target SafeRelease(m_pD2DRenderTarget); HRESULT hr = m_pD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(this->GetSafeHwnd(), D2D1::SizeU(m_rtViewRect.Width(), m_rtViewRect.Height())), &m_pD2DRenderTarget); if (hr!=S_OK) { return FALSE; } auto rtSize = m_pD2DRenderTarget->GetSize(); m_rtRenderRect = D2D1::RectF(0.0f, 0.0f, rtSize.width, rtSize.height); return TRUE; } int CImageViewer::CreateWicBitmap(int nWidthStep, int nHeight, int nChannels, BYTE* pBuffer) { CSingleLock myLock(m_pD2DCriticalSection); myLock.Lock(); if (m_nWicBitmapWidthStep==nWidthStep && m_nWicBitmapHeight==nHeight && m_nWicBitmapChannels==nChannels && m_pWICBitmap!=nullptr) return 1; m_nWicBitmapWidthStep = nWidthStep; m_nWicBitmapHeight = nHeight; m_nWicBitmapChannels = nChannels; GUID pixelFormat = GUID_WICPixelFormat32bppBGRA; switch(nChannels) { case 1: pixelFormat = GUID_WICPixelFormat8bppGray; break; case 3: pixelFormat = GUID_WICPixelFormat24bppBGR; break; case 4: pixelFormat = GUID_WICPixelFormat32bppBGRA; break; } // create wic bitmap SafeRelease(m_pWICBitmap); HRESULT hr = m_pWICFactory->CreateBitmapFromMemory( m_nWicBitmapWidthStep/m_nWicBitmapChannels, m_nWicBitmapHeight, pixelFormat, m_nWicBitmapWidthStep, m_nWicBitmapWidthStep*m_nWicBitmapHeight, pBuffer, &m_pWICBitmap); if (hr!=S_OK) { return 0; } // create format converter SafeRelease(m_pWICFormatConverter); hr = m_pWICFactory->CreateFormatConverter(&m_pWICFormatConverter); if (hr!=S_OK) { return 0; } // initialize format converter hr = m_pWICFormatConverter->Initialize( m_pWICBitmap, // Input source to convert GUID_WICPixelFormat32bppPBGRA, // Destination pixel format WICBitmapDitherTypeNone, // Specified dither pattern NULL, // Specify a particular palette 0.f, // Alpha threshold WICBitmapPaletteTypeCustom // Palette translation type ); if (hr!=S_OK) { return 0; } return 2; } void CImageViewer::CalculateRect() { switch(m_nViewType) { case ViewScale_Fit: { m_rtDestRect = m_rtRenderRect; m_rtSourceRect = D2D1::RectF(0.0f, 0.0f, (float)GetWidth(), (float)GetHeight()); } break; case ViewScale_Origin: { int nImageWidth = cv::min(GetWidth(), (int)m_rtRenderRect.right); int nImageHeight = cv::min(GetHeight(), (int)m_rtRenderRect.bottom); m_rtDestRect = D2D1::RectF(0.0f, 0.0f, (float)nImageWidth, (float)nImageHeight); m_rtSourceRect = D2D1::RectF((float)m_nHScroll, (float)m_nVScroll, float(m_nHScroll+nImageWidth), float(m_nVScroll+nImageHeight)); } break; case ViewScale_Zoom: { int nSrcWidth = GetWidth(); int nSrcHeight = GetHeight(); int nScaleWidth = int(double(nSrcWidth) * m_dWidthScale + 0.5); int nScaleHeight = int(double(nSrcHeight) * m_dHeightScale + 0.5); if (m_nScaleWidth!=nScaleWidth || m_nScaleHeight!=nScaleHeight) SetViewType(m_nViewType); int nImageWidth = cv::min(nScaleWidth, (int)m_rtRenderRect.right); int nImageHeight = cv::min(nScaleHeight, (int)m_rtRenderRect.bottom); m_rtDestRect = D2D1::RectF(0.0f, 0.0f, (float)nImageWidth, (float)nImageHeight); if (m_rtViewRect.Width() < nScaleWidth) { m_rtSourceRect.left = FLOAT(int(double(m_nHScroll) / m_dWidthScale)); m_rtSourceRect.right = FLOAT(m_rtSourceRect.left + int(double(m_rtOrgViewRect.Width()) / m_dWidthScale)); } else { m_rtSourceRect.left = 0.f; m_rtSourceRect.right = FLOAT(nSrcWidth); } if (m_rtViewRect.Height() < nScaleHeight) { m_rtSourceRect.top = FLOAT(int(double(m_nVScroll) / m_dHeightScale)); m_rtSourceRect.bottom = FLOAT(m_rtSourceRect.top + int(double(m_rtOrgViewRect.Height()) / m_dHeightScale)); } else { m_rtSourceRect.top = 0; m_rtSourceRect.bottom = FLOAT(nSrcHeight); } } break; } } void CImageViewer::OnPaint() { CPaintDC dc(this); // device context for painting CRect rect; GetClientRect(rect); // create render target if (CreateRenderTarget(rect)==FALSE) { return; } // image exist? if (GetImageExist()==FALSE) { m_pD2DRenderTarget->BeginDraw(); m_pD2DRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Gray)); m_pD2DRenderTarget->EndDraw(); return; } // create wic bitmap int nCode = CreateWicBitmap(GetWidthStep(), GetHeight(), GetChannels(), (BYTE*)GetImageBuffer()); if (nCode==0) { return; } // create d2d bitmap if (nCode==2 && m_pWICFormatConverter && m_pD2DRenderTarget) { SafeRelease(m_pD2DBitmap); HRESULT hr = m_pD2DRenderTarget->CreateBitmapFromWicBitmap(m_pWICFormatConverter, 0, &m_pD2DBitmap); if (hr!=S_OK) { return; } } // draw if (m_pD2DRenderTarget && m_pD2DBitmap) { // cal rect CalculateRect(); m_pD2DRenderTarget->BeginDraw(); m_pD2DRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Gray)); // set anti alias mode if (m_pD2DRenderTarget->GetAntialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED) { m_pD2DRenderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); } // draw image m_pD2DRenderTarget->DrawBitmap(m_pD2DBitmap, m_rtDestRect, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, m_rtSourceRect); // draw view name if (m_bDrawViewName) DrawViewName(); // draw object if (m_bDrawObject) DrawObject(); // draw roi if (m_bDrawRoi) DrawRoi(); m_pD2DRenderTarget->EndDraw(); } return; } void CImageViewer::DrawObject() { if (m_pD2DRenderTarget==NULL) return; for (ListDrawObjectIt it=m_listDrawObject.begin(); it!=m_listDrawObject.end(); it++) { DrawObject(*it); } } void CImageViewer::DrawViewName() { } void CImageViewer::DrawRoi() { D2D1_RECT_F rect = D2D1::RectF( FLOAT(m_rtRoiRect.Left()), FLOAT(m_rtRoiRect.Top()), FLOAT(m_rtRoiRect.Right()), FLOAT(m_rtRoiRect.Bottom()) ); if (IntersectsWith(m_rtSourceRect, rect)==FALSE) return; float fPenSize = FLOAT(m_rtRoiRect.dPenSize * m_dWidthScale); D2D1_RECT_F target; target.left = FLOAT(int(m_rtRoiRect.Left() * m_dWidthScale + 0.5) - m_nHScroll); target.top = FLOAT(int(m_rtRoiRect.Top() * m_dHeightScale + 0.5) - m_nVScroll); target.right = FLOAT(int(m_rtRoiRect.Right() * m_dWidthScale + 0.5) - m_nHScroll); target.bottom = FLOAT(int(m_rtRoiRect.Bottom() * m_dHeightScale + 0.5) - m_nVScroll); ID2D1SolidColorBrush *pPen = NULL; HRESULT hr = m_pD2DRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(m_rtRoiRect.nPenColor, FLOAT(m_rtRoiRect.dPenOpacity))),&pPen); ID2D1SolidColorBrush *pBrush = NULL; hr = m_pD2DRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(m_rtRoiRect.nBrushColor, FLOAT(m_rtRoiRect.dBrushOpacity))),&pBrush); m_pD2DRenderTarget->FillRectangle(target, pBrush); m_pD2DRenderTarget->DrawRectangle(target, pPen, fPenSize); SafeRelease(pPen); SafeRelease(pBrush); } void CImageViewer::DrawObject(const SDrawObject& object) { D2D1_RECT_F rect = D2D1::RectF( FLOAT(object.Left()), FLOAT(object.Top()), FLOAT(object.Right()), FLOAT(object.Bottom()) ); if (IntersectsWith(m_rtSourceRect, rect)==FALSE) return; //float fPenSize = FLOAT(object.dPenSize * m_dWidthScale); float fPenSize = FLOAT(object.dPenSize); D2D1_RECT_F target; target.left = FLOAT(int(object.Left() * m_dWidthScale + 0.5) - m_nHScroll); target.top = FLOAT(int(object.Top() * m_dHeightScale + 0.5) - m_nVScroll); target.right = FLOAT(int(object.Right() * m_dWidthScale + 0.5) - m_nHScroll); target.bottom = FLOAT(int(object.Bottom() * m_dHeightScale + 0.5) - m_nVScroll); float fScaleWidth = FLOAT(GetScaleWidth()); float fScaleHeight = FLOAT(GetScaleHeight()); if (target.left > fScaleWidth) target.left = fScaleWidth; if (target.top > fScaleHeight) target.top = fScaleHeight; if (target.right > fScaleWidth) target.right = fScaleWidth; if (target.bottom > fScaleHeight) target.bottom = fScaleHeight; ID2D1SolidColorBrush *pPen = NULL; HRESULT hr = m_pD2DRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(object.nPenColor, FLOAT(object.dPenOpacity))),&pPen); ID2D1SolidColorBrush *pBrush = NULL; hr = m_pD2DRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF(object.nBrushColor, FLOAT(object.dBrushOpacity))),&pBrush); switch(object.nType) { case DrawObject_Line: { m_pD2DRenderTarget->DrawLine(D2D1::Point2F(target.left, target.top), D2D1::Point2F(target.right, target.bottom), pPen, fPenSize); } break; case DrawObject_Rectangle: { m_pD2DRenderTarget->FillRectangle(target, pBrush); m_pD2DRenderTarget->DrawRectangle(target, pPen, fPenSize); } break; case DrawObject_Ellipse: { D2D1_ELLIPSE ellipse; ellipse.radiusX = (target.right - target.left) / 2.0f; ellipse.radiusY = (target.bottom - target.top) / 2.0f; ellipse.point = D2D1::Point2F(FLOAT(target.left+ellipse.radiusX), FLOAT(target.top+ellipse.radiusY)); m_pD2DRenderTarget->FillEllipse(ellipse, pBrush); m_pD2DRenderTarget->DrawEllipse(ellipse, pPen, fPenSize); } break; case DrawObject_Polygon: { ID2D1PathGeometry* pPathGeometry = nullptr; m_pD2DFactory->CreatePathGeometry(&pPathGeometry); if (pPathGeometry) { ID2D1GeometrySink* pGeometrySink = nullptr; pPathGeometry->Open(&pGeometrySink); if (pGeometrySink) { D2D1_POINT_2F fb; fb.x = FLOAT(object.vecPolygon[0].dPosX*m_dWidthScale) + target.left; fb.y = FLOAT(object.vecPolygon[0].dPosY*m_dHeightScale) + target.top; // Use D2D1_FIGURE_BEGIN_FILLED for filled D2D1_FIGURE_BEGIN fg = D2D1_FIGURE_BEGIN_FILLED; D2D1_FIGURE_END fe = D2D1_FIGURE_END_CLOSED; pGeometrySink->BeginFigure(fb, fg); int nCount = (int)object.vecPolygon.size(); for (int nIdx=1; nIdxAddLine(fu); } pGeometrySink->EndFigure(fe); pGeometrySink->Close(); SafeRelease(pGeometrySink); } m_pD2DRenderTarget->FillGeometry(pPathGeometry, pBrush); m_pD2DRenderTarget->DrawGeometry(pPathGeometry, pPen, fPenSize); SafeRelease(pPathGeometry); } } break; } SafeRelease(pPen); SafeRelease(pBrush); } BOOL CImageViewer::LoadImage(const CString& strFilename) { if (CImageBuffer::LoadImage(strFilename)==FALSE) { return FALSE; } m_nWicBitmapWidthStep = 0; m_nWicBitmapHeight = 0; m_nWicBitmapChannels = 0; SetViewType(m_nViewType); m_rtRoiRect.dPosX = GetWidth() / 4; m_rtRoiRect.dPosY = GetHeight() / 4; m_rtRoiRect.dSizeX = m_rtRoiRect.dPosX * 2.0; m_rtRoiRect.dSizeY = m_rtRoiRect.dPosY * 2.0; m_rtRoiRect.dPenOpacity = 1.0; m_rtRoiRect.dPenSize = 2; m_rtRoiRect.dBrushOpacity = 0.0; return TRUE; } void CImageViewer::SetViewType(int nType) { m_nViewType = nType; m_nScaleWidth = GetScaleWidth(); m_nScaleHeight = GetScaleHeight(); switch(m_nViewType) { case ViewScale_Origin: if (m_rtOrgViewRect.Width() >= m_nScaleWidth) { m_nMaxHScroll = 0; } else { m_nMaxHScroll = m_nScaleWidth - (m_rtOrgViewRect.Width()+17); if (m_nMaxHScroll < 0) { m_nMaxHScroll = 0; } else { m_nMaxHScroll += 17; } } if (m_rtOrgViewRect.Height() >= m_nScaleHeight) { m_nMaxVScroll = 0; } else { m_nMaxVScroll = m_nScaleHeight - (m_rtOrgViewRect.Height()+17); if (m_nMaxVScroll < 0) { m_nMaxVScroll = 0; } else { m_nMaxVScroll += 17; } } break; case ViewScale_Zoom: m_nMaxHScroll = m_nScaleWidth - (m_rtOrgViewRect.Width()+17); m_nMaxVScroll = m_nScaleHeight - (m_rtOrgViewRect.Height()+17); if (m_nMaxVScroll < 0) { m_nMaxVScroll = 0; } else { m_nMaxVScroll += 17; } if (m_nMaxHScroll < 0) { m_nMaxHScroll = 0; } else { m_nMaxHScroll += 17; } break; case ViewScale_Fit: m_nMaxHScroll = m_nMaxVScroll = 0; break; } m_nHScroll = m_nVScroll = 0; SetScrollRange(SB_HORZ, 0, m_nMaxHScroll); SetScrollRange(SB_VERT, 0, m_nMaxVScroll); SetScrollPos(SB_HORZ, m_nHScroll); SetScrollPos(SB_VERT, m_nVScroll); // update view rect GetClientRect(m_rtViewRect); return; } int CImageViewer::GetScaleWidth() { CRect rect; int nWidth = GetWidth(); switch(m_nViewType) { case ViewScale_Origin: m_dWidthScale = 1.0; return nWidth; case ViewScale_Zoom: return int(double(nWidth) * m_dWidthScale + 0.5); case ViewScale_Fit: if (nWidth!=0) m_dWidthScale = double(m_rtOrgViewRect.Width()) / double(nWidth); return int(double(nWidth) * m_dWidthScale + 0.5); } return 0; } int CImageViewer::GetScaleHeight() { CRect rect; int nHeight = GetHeight(); switch(m_nViewType) { case ViewScale_Origin: m_dHeightScale = 1.0; return nHeight; case ViewScale_Zoom: return int(double(nHeight) * m_dHeightScale + 0.5); case ViewScale_Fit: if (nHeight!=0) m_dHeightScale = double(m_rtOrgViewRect.Height()) / double(nHeight); return int(double(nHeight) * m_dHeightScale + 0.5); } return 0; } void CImageViewer::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { switch (nSBCode) { case SB_LEFT: // Scroll to far left. break; case SB_RIGHT: // Scroll to far right. break; case SB_ENDSCROLL: // End scroll. break; case SB_LINELEFT: // Scroll left. if (m_nHScroll > 0) m_nHScroll -= 10; //m_nHScroll--; break; case SB_LINERIGHT: // Scroll right. if (m_nHScroll < m_nMaxHScroll) m_nHScroll += 10; //m_nHScroll++; break; case SB_PAGELEFT: // Scroll one page left. if (5 < m_nMaxHScroll / 256) m_nHScroll -= 40;//m_nHScroll -= 5; else m_nHScroll -= 20;//m_nHScroll -= m_nMaxHScroll / 256; if (m_nHScroll < 0) m_nHScroll = 0; break; case SB_PAGERIGHT: // Scroll one page right. if (5 < m_nMaxHScroll / 256) m_nHScroll += 40;//m_nHScroll += 5; else m_nHScroll += 20;//m_nHScroll += m_nMaxHScroll / 256; if (m_nHScroll > m_nMaxHScroll) m_nHScroll = m_nMaxHScroll; break; case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position break; case SB_THUMBTRACK: // Drag scroll box to specified position. nPos is the m_nHScroll = nPos; TRACE(_T("Horz SB_THUMBTRACK : %d\n"), nPos); break; } // Set the new position of the thumb (scroll box). SetScrollPos(SB_HORZ, m_nHScroll); Invalidate(FALSE); __super::OnHScroll(nSBCode, nPos, pScrollBar); } void CImageViewer::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { switch (nSBCode) { case SB_BOTTOM: // Scroll to bottom. break; case SB_ENDSCROLL: // End scroll. break; case SB_LINEDOWN: // Scroll one line down. if (m_nVScroll < m_nMaxVScroll) m_nVScroll += 10; //m_nVScroll++; break; case SB_LINEUP: // Scroll one line up. if (m_nVScroll > 0) m_nVScroll -= 10; //m_nVScroll--; break; case SB_PAGEDOWN: // Scroll one page down. if (5 < m_nMaxVScroll / 256) m_nVScroll += 40;//m_nVScroll += 5; else m_nVScroll += 20;//m_nVScroll += (m_nMaxVScroll / 256); if (m_nVScroll > m_nMaxVScroll) m_nVScroll = m_nMaxVScroll; break; case SB_PAGEUP: // Scroll one page up. if (5 < m_nMaxVScroll / 256) m_nVScroll -= 40;//m_nVScroll -= 5; else m_nVScroll -= 20;//m_nVScroll -= (m_nMaxVScroll / 256); if (m_nVScroll < 0) m_nVScroll = 0; break; case SB_THUMBPOSITION: // Scroll to the absolute position. The current position is provided in nPos. break; case SB_THUMBTRACK: // Drag scroll box to specified position. The current position is provided in nPos. m_nVScroll = nPos; TRACE(_T("Vert SB_THUMBTRACK : %d\n"), nPos); break; case SB_TOP: // Scroll to top. break; } // Set the new position of the thumb (scroll box). SetScrollPos(SB_VERT, m_nVScroll); Invalidate(FALSE); __super::OnVScroll(nSBCode, nPos, pScrollBar); } void CImageViewer::SetDrawObject( BOOL bDraw ) { m_bDrawObject = bDraw; } void CImageViewer::SetDrawRoi( BOOL bDraw ) { m_bDrawRoi = bDraw; } void CImageViewer::SetWidthScale( double dScale ) { m_dWidthScale = dScale; } void CImageViewer::SetHeightScale( double dScale ) { m_dHeightScale = dScale; } void CImageViewer::SetScale( double dScale ) { m_dWidthScale = m_dHeightScale = dScale; } int CImageViewer::GetViewType() const { return m_nViewType; } BOOL CImageViewer::GetDrawObject() const { return m_bDrawObject; } BOOL CImageViewer::GetDrawRoi() const { return m_bDrawRoi; } double CImageViewer::GetWidthScale( void ) const { return m_dWidthScale; } double CImageViewer::GetHeightScale( void ) const { return m_dHeightScale; } double CImageViewer::GetScale() const { return (m_dWidthScale+m_dHeightScale) / 2.0; } int CImageViewer::GetHScrollPos( void ) const { return m_nHScroll; } int CImageViewer::GetVScrollPos( void ) const { return m_nVScroll; } void CImageViewer::AddDrawObject( const SDrawObject& drawObject ) { m_listDrawObject.push_back(drawObject); } void CImageViewer::DeleteAllDrawObject( void ) { m_listDrawObject.clear(); } void CImageViewer::ClearScreen() { CPaintDC dc(this); // device context for painting m_pD2DRenderTarget->BeginDraw(); m_pD2DRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Gray)); m_pD2DRenderTarget->EndDraw(); return; } void CImageViewer::OnSize(UINT nType, int cx, int cy) { __super::OnSize(nType, cx, cy); return; } int CImageViewer::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (__super::OnCreate(lpCreateStruct) == -1) return -1; GetClientRect(m_rtOrgViewRect); return 0; } void CImageViewer::SetDrawViewName( BOOL bDraw ) { m_bDrawViewName = bDraw; } BOOL CImageViewer::GetDrawViewName() const { return m_bDrawViewName; } void CImageViewer::SetViewName( const CString& strValue ) { m_strViewName = strValue; } void CImageViewer::SetRoiRect( const CRect& rtRect ) { m_rtRoiRect.dPosX = rtRect.left; m_rtRoiRect.dPosY = rtRect.top; m_rtRoiRect.dSizeX = rtRect.Width(); m_rtRoiRect.dSizeY = rtRect.Height(); } CString CImageViewer::GetViewName() const { return m_strViewName; } CRect CImageViewer::GetRoiRect() const { CRect rect; rect.left = (int) (m_rtRoiRect.dPosX + 0.5); rect.top = (int) (m_rtRoiRect.dPosY + 0.5); rect.right = rect.left + (int) (m_rtRoiRect.dSizeX + 0.5); rect.bottom = rect.top + (int) (m_rtRoiRect.dSizeY + 0.5); return rect; }