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

📄 imageviewerview.cpp

📁 图像显示软件源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
}
#endif //_DEBUG


// CImageViewerView message handlers

bool CImageViewerView::SetCurrentImage(size_t nImage, bool PassLock)
{
    CImageViewerDoc *pDoc = GetDocument();

    // First make sure nImage is in range
    if (NULL != pDoc && nImage < pDoc->GetImageDataCount())
    {
        // Is the display locked? Can we get past it?
        if (PassLock || !AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0))
        {
            // clean up the old bitmap
            CurrentBitmap.DeleteObject();
            ZoomedBitmapRect.SetRectEmpty();
            CurrentImage = nImage;
            GetParent()->SendMessage(WMU_SETMESSAGETEXT, 0, 0);

            // and get the data for the new one
            CImageData *pData = pDoc->GetImageData(CurrentImage);
            if (NULL != pData)
            {
                CurrentBitmap = pja::CBitmap(pData->GetBitmap());
                CSize Size;
                Size.cx = CurrentBitmap.Width() * ZoomRatios[CurrentZoomRatio] / 100;
                Size.cy = CurrentBitmap.Height() * ZoomRatios[CurrentZoomRatio] / 100;

                long LineSize = ZoomRatios[CurrentZoomRatio] / 100;
                if (LineSize < 1)
                    LineSize = 1;

                SetScrollSizes(MM_TEXT, Size, sizeDefault, CSize(LineSize, LineSize));

                // center the bitmap on the view if the bitmap is smaller than the view
                ZoomedBitmapRect.SetRect(0, 0, Size.cx, Size.cy);
                CalcBitmapRect();

                GetParent()->SendMessage(WMU_SETMESSAGETEXT,
                                         0,
                                         reinterpret_cast<LPARAM>(pDoc->GetImageData(CurrentImage)));
                AfxGetMainWnd()->SendMessage(WMU_UPDATETOOLTIP,
                                             reinterpret_cast<WPARAM>(this), 0);
                AfxGetMainWnd()->SendMessage(WMU_SETPROPERTIES,
                                             reinterpret_cast<WPARAM>(GetParent()),
                                             reinterpret_cast<LPARAM>(pDoc->GetImageData(CurrentImage)));
            }
        }
    }

    // force the view window to refresh
    Invalidate();
    SetCaption();
    return true;
}

void CImageViewerView::SetCaption()
{
    // set the view's caption bar text
    CImageViewerDoc *pDoc = GetDocument();
    pja::CFormat cf;
    GetParent()->SetWindowText(cf.MakeMessage(NULL,
                                              IDS_CAPTION,
                                              4,
                                              pDoc->GetCaption(),
                                              cf.TS(CurrentImage + 1),
                                              cf.TS(pDoc->GetImageDataCount()),
                                              cf.TS(ZoomRatios[CurrentZoomRatio])).c_str());
}

void CImageViewerView::OnImageFirst()
{
    bool locked = AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0) != 0;
    if (!locked)
    {
        AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
        AfxGetApp()->OnIdle(-1);
    }
    SetCurrentImage(0, true);
}

void CImageViewerView::OnUpdateImageFirst(CCmdUI *pCmdUI)
{
    pCmdUI->Enable(CurrentImage != 0);
}

void CImageViewerView::OnImagePrevious()
{
    bool locked = AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0) != 0;
    if (!locked)
    {
        AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
        AfxGetApp()->OnIdle(-1);
    }
    SetCurrentImage(CurrentImage - 1, true);
}

void CImageViewerView::OnUpdateImagePrevious(CCmdUI *pCmdUI)
{
    pCmdUI->Enable(CurrentImage != 0);
}

void CImageViewerView::OnImageSelect()
{
    CImageViewerDoc *pDoc = GetDocument();
    if (pDoc)
    {
        bool locked = AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0) != 0;
        if (!locked)
        {
            AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
            AfxGetApp()->OnIdle(-1);
        }
        CSelectImageDialog Dlg(this);
        Dlg.m_Image = (UINT)CurrentImage + 1;
        Dlg.m_MaxImage = (UINT)pDoc->GetImageDataCount();
        if (Dlg.DoModal() == IDOK)
        {
            SetCurrentImage(Dlg.m_Image - 1, true);
        }
        else if (!locked)
        {
            AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
        }
    }
}

void CImageViewerView::OnUpdateImageSelect(CCmdUI *pCmdUI)
{
    bool Enable = false;
    CImageViewerDoc *pDoc = GetDocument();
    if (pDoc)
    {
        Enable = pDoc->GetImageDataCount() > 1;
    }

    pCmdUI->Enable(Enable);
}

void CImageViewerView::OnImageNext()
{
    bool locked = AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0) != 0;
    if (!locked)
    {
        AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
        AfxGetApp()->OnIdle(-1);
    }

    SetCurrentImage(CurrentImage + 1, true);
}

void CImageViewerView::OnUpdateImageNext(CCmdUI *pCmdUI)
{
    bool Enable = false;
    CImageViewerDoc *pDoc = GetDocument();
    if (pDoc)
    {
        Enable = pDoc->GetImageDataCount() > CurrentImage + 1;
    }

    pCmdUI->Enable(Enable);
}

void CImageViewerView::OnImageLast()
{
    bool locked = AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0) != 0;
    if (!locked)
    {
        AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
        AfxGetApp()->OnIdle(-1);
    }
    CImageViewerDoc *pDoc = GetDocument();
    if (pDoc)
    {
        SetCurrentImage(pDoc->GetImageDataCount() - 1, true);
    }
}

void CImageViewerView::OnUpdateImageLast(CCmdUI *pCmdUI)
{
    bool Enable = false;
    CImageViewerDoc *pDoc = GetDocument();
    if (pDoc)
    {
        Enable = pDoc->GetImageDataCount() > CurrentImage + 1;
    }

    pCmdUI->Enable(Enable);
}

void CImageViewerView::OnZoomZoomIn()
{
    if (CurrentZoomRatio < _countof(ZoomRatios) - 1)
    {
        SetRedraw(FALSE);
        CPoint Cursor;
        GetCursorPos(&Cursor);
        CPoint Pixel(-1, -1);
        if (GetVisibleRect().PtInRect(Cursor))
        {
            ScreenToClient(&Cursor);
            Pixel = GetPixelFromPoint(Cursor, false);
        }

        ++CurrentZoomRatio;
        SetCurrentImage(CurrentImage, true);

        MovePixelToPoint(Pixel, Cursor);
        SetRedraw(TRUE);
        RedrawWindow();
    }
}

void CImageViewerView::OnUpdateZoomZoomIn(CCmdUI *pCmdUI)
{
    pCmdUI->Enable(CurrentZoomRatio < _countof(ZoomRatios) - 1);
}

void CImageViewerView::OnZoomZoomOut()
{
    if (CurrentZoomRatio > 0)
    {
        SetRedraw(FALSE);
        CPoint Cursor;
        GetCursorPos(&Cursor);
        CPoint Pixel(-1, -1);
        if (GetVisibleRect().PtInRect(Cursor))
        {
            ScreenToClient(&Cursor);
            Pixel = GetPixelFromPoint(Cursor, false);
        }

        --CurrentZoomRatio;
        SetCurrentImage(CurrentImage, true);

        MovePixelToPoint(Pixel, Cursor);
        SetRedraw(TRUE);
        RedrawWindow();
    }
}

void CImageViewerView::OnUpdateZoomZoomOut(CCmdUI *pCmdUI)
{
    pCmdUI->Enable(CurrentZoomRatio > 0);
}

// When zooming in or out this keeps the same image pixel centered under the mouse cursor
void CImageViewerView::MovePixelToPoint(CPoint Pixel, CPoint Client)
{
    // Pixel - The pixel that you want at the supplied point
    // Client - The point, in the view's client coords, where you want the supplied pixel
    if (PtInRect(CurrentBitmap.Rect(), Pixel))
    {
        CPoint CurrentPosition = GetDeviceScrollPosition();
        CPoint CurrentPixel = GetPixelFromPoint(Client, false);
        CurrentPosition.x += (Pixel.x - CurrentPixel.x) * ZoomRatios[CurrentZoomRatio] / 100;
        if (ZoomRatios[CurrentZoomRatio] > 200)
        {
            long left = Pixel.x * ZoomRatios[CurrentZoomRatio] / 100 - CurrentPosition.x;
            long diff = Client.x - left;
            CurrentPosition.x -= diff;
            CurrentPosition.x += ZoomRatios[CurrentZoomRatio] / 200;
        }

        CurrentPosition.y += (Pixel.y - CurrentPixel.y) * ZoomRatios[CurrentZoomRatio] / 100;
        if (ZoomRatios[CurrentZoomRatio] > 200)
        {
            long top = Pixel.y * ZoomRatios[CurrentZoomRatio] / 100 - CurrentPosition.y;
            long diff = Client.y - top;
            CurrentPosition.y -= diff;
            CurrentPosition.y += ZoomRatios[CurrentZoomRatio] / 200;
        }

        long MaxHorz = 0;
        if (GetStyle() & WS_HSCROLL)
        {
            MaxHorz = GetScrollLimit(SB_HORZ);
        }

        long MaxVert = 0;
        if (GetStyle() & WS_VSCROLL)
        {
            MaxVert = GetScrollLimit(SB_VERT);
        }

        if (CurrentPosition.x < 0)
        {
            CurrentPosition.x = 0;
        }
        if (CurrentPosition.x > MaxHorz)
        {
            CurrentPosition.x = MaxHorz;
        }
        if (CurrentPosition.y < 0)
        {
            CurrentPosition.y = 0;
        }
        if (CurrentPosition.y > MaxVert)
        {
            CurrentPosition.y = MaxVert;
        }

        ScrollToPosition(CurrentPosition);
        AfxGetMainWnd()->SendMessage(WMU_UPDATETOOLTIP, (WPARAM)this, 0);
    }
}

void CImageViewerView::OnZoomGrid()
{
    ViewGrid = !ViewGrid;
    SetCurrentImage(CurrentImage, true);
}

void CImageViewerView::OnUpdateZoomGrid(CCmdUI *pCmdUI)
{
    pCmdUI->SetCheck(ViewGrid ? BST_CHECKED : BST_UNCHECKED);
}

void CImageViewerView::OnMButtonDown(UINT, CPoint point)
{
    try
    {
        new pja::CWindowScroller(this, point);
    }

    catch (CMemoryException *me)
    {
        theApp.MemoryEvent.ResetEvent();
        me->ReportError();
        me->Delete();
    }
}

// Handler for the WMU_GETPOINTDATA message sent by the tooltip
LRESULT CImageViewerView::OnGetPointData(WPARAM, LPARAM lp)
{
    if (!ZoomedBitmapRect.IsRectEmpty())
    {
        CTooltipWindow::PointData *PointData = reinterpret_cast<CTooltipWindow::PointData *>(lp);

        ScreenToClient(&PointData->Point);

        CRect ClientRect;
        GetClientRect(ClientRect);
        if (ClientRect.PtInRect(PointData->Point))
        {
            PointData->Point += GetDeviceScrollPosition();
            if (ZoomRatios[CurrentZoomRatio] > 99 && ZoomedBitmapRect.PtInRect(PointData->Point))
            {
                PointData->Point = GetPixelFromPoint(PointData->Point);
                PointData->Colour = GetPixelColour(PointData->Point);

                if (CLR_NONE != PointData->Colour)
                {
                    // if we are dealing with just a region or one that that has negative coordinates
                    // then adjust the tooltip's reported coordinates to reflect the region
                    CImageData *pImageData = GetDocument()->GetImageData(CurrentImage);
                    CBitmapInfoHeader BitmapInfoHeader(pImageData->GetBitmapInfoHeader());
                    CRect RegionRect(pImageData->GetRegionRect());

                    if (RegionRect.left < 0 || RegionRect.Width() == BitmapInfoHeader.biWidth)
                    {
                        PointData->Point.x += RegionRect.left;
                    }

                    if (RegionRect.top < 0 || RegionRect.Height() == BitmapInfoHeader.biHeight)
                    {
                        PointData->Point.y += RegionRect.top;
                    }
                }
                return 1;
            }
        }
    }

    return 0;
}

// returns the colour of the pixel at the supplied point in the image
COLORREF CImageViewerView::GetPixelColour(CPoint &pt) const
{
    COLORREF ret = CLR_NONE;

    if (pt.x >= 0 && pt.x < CurrentBitmap.Width() && pt.y >= 0 && pt.y < CurrentBitmap.Height())
    {
        pja::CCompatibleDC DC;
        SelectObject(DC, CurrentBitmap);
        ret = GetPixel(DC, pt.x, pt.y);
    }

    return ret;
}

// returns a CPoint that contains the pixel coords that is located
// at the supplied client coords
CPoint CImageViewerView::GetPixelFromPoint(CPoint Point, bool AdjustedForScrolling /* = true */)
{
    CPoint pt;

    if (!AdjustedForScrolling)
    {
        Point += GetDeviceScrollPosition();
    }

    pt.x = (Point.x - ZoomedBitmapRect.left) * 100 / ZoomRatios[CurrentZoomRatio];
    pt.y = (Point.y - ZoomedBitmapRect.top) * 100 / ZoomRatios[CurrentZoomRatio];

    return pt;
}

void CImageViewerView::OnImageDelete()
{
    bool locked = AfxGetMainWnd()->SendMessage(WMU_GETDISPLAYLOCK, 0, 0) != 0;
    if (!locked)
    {
        // temporarily lock the display
        AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_DISPLAY_LOCK, 0);
        AfxGetApp()->OnIdle(-1);
    }

    CImageViewerDoc *pDoc = GetDocument();

    CDeleteImageDialog Dlg(this);
    Dlg.To = pDoc->GetImageDataCount() - 1;

⌨️ 快捷键说明

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