📄 imageviewerview.cpp
字号:
}
#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 + -