Files
Slnkdwf/Viewer/SLNKDWFViewerView.cpp
2020-05-19 10:52:05 +00:00

388 lines
9.9 KiB
C++

// SLNKDwfViewerView.cpp : implementation of the CSLNKDwfViewerView class
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "atlgdix.h"
#include "SLNKDwfViewerView.h"
#define SCL 1
CSLNKDwfViewerView::CSLNKDwfViewerView(CMainFrame& parent): m_Parent(parent)
{
m_nPage = 0;
m_busyPanning = FALSE;
m_Bitmap = NULL;
}
CSLNKDwfViewerView::~CSLNKDwfViewerView()
{
if (m_Bitmap != NULL) delete m_Bitmap;
}
BOOL CSLNKDwfViewerView::PreTranslateMessage(MSG* pMsg)
{
pMsg;
return FALSE;
}
void CSLNKDwfViewerView::SetDWF(const CString &dwfPath)
{
m_dwfPath = dwfPath;
if (m_Bitmap != NULL)
{
delete m_Bitmap; // It is dirty
m_Bitmap = NULL;
}
SetZoomMode(ZOOMMODE_IN);
SetPage(0);
}
void DoMessage(CDCHandle dc, const CString msg)
{
CRect clrc;
dc.GetClipBox(clrc);
FillRect(dc,clrc,GetSysColorBrush( COLOR_WINDOW ));
SetTextColor(dc, GetSysColor( COLOR_WINDOWTEXT ));
CString tok(msg);
tok.Replace("~", "\n"); // We ondersteunen ook ~ als newline
RECT rc = { 0, 0, clrc.Width(), 0};
GetClientRect(dc.WindowFromDC(), clrc);
int height = DrawText(dc, tok, tok.GetLength(), &rc, DT_CALCRECT); // Grootte bepalen
rc.top = clrc.Height()/2 - rc.bottom/2; // Vertikaal centreren
rc.bottom = clrc.Height()/2 + rc.bottom/2;
height = DrawText(dc, tok, tok.GetLength(), &rc, DT_TOP);
ATLASSERT(height);
}
void PaintToDC(HDC dc, CString dwfPath, int nPage,
CWhip2DCImpl &iWhip2DC, CSize wSize,
BOOL forPrint /*=FALSE*/)
{
try {
CDWFFileImpl m_iDWFFile;
CEPlotSectionsImpl *piEPlotSections;
m_iDWFFile.Open(dwfPath);
piEPlotSections = m_iDWFFile.get_EPlotSections();
LONG lCount = piEPlotSections->get_Count();
if (lCount > 0)
{
iWhip2DC.Load(dc, piEPlotSections->get_Item(nPage), L"", L".*",
wSize.cx, wSize.cy, VARIANT_TRUE /*center*/, VARIANT_FALSE /* Maximize */);
}
else
{
iWhip2DC.Load(dc, NULL, dwfPath, L".*",
wSize.cx, wSize.cy, VARIANT_TRUE /*center*/, VARIANT_FALSE /* Maximize */);
}
//int mm = GetMapMode(dc);
//SetMapMode(dc, MM_TEXT);
//SetMapMode(dc, MM_ANISOTROPIC);
if (forPrint)
iWhip2DC.put_paperColor(0xFFFFFF); // Altijd wit papier
iWhip2DC.Paint(VARIANT_FALSE, 1); // geen bw, auto markers
//SetMapMode(dc, mm);
}
catch (CString &ee)
{
DoMessage(dc, ee);
}
catch (...)
{
DoMessage(dc, "Unhandled Exception");
}
}
BOOL DoEvents()
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message==WM_QUIT)
return FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
BOOL CSLNKDwfViewerView::my_progress_action(void *param, double progress)
{
CSLNKDwfViewerView *vw = (CSLNKDwfViewerView *)param;
// Erg instabiel (door recursieve WM_PAINT?)
// if (!DoEvents())
// return FALSE;
if (GetSystemMetrics(SM_REMOTESESSION))
{ // App is running on a remote session.
return TRUE; // Geen preview bij terminal services
}
if (GetTickCount() - vw->m_Timer > 333)
{ // Preview time
// Tijdens het blitten willen we geen vertalingen
CRect rc;
vw->GetClientRect(rc);
SIZE orgSize;
::SetViewportExtEx(vw->m_hDCOriginal, rc.Size().cx, rc.Size().cy, &orgSize);
CPoint pt;
::GetViewportOrgEx(vw->m_hDCOriginal, &pt);
CPoint pt2;
vw->m_MemDC.SetViewportOrg(0,0, &pt2);
::BitBlt(vw->m_hDCOriginal,
-pt.x, -pt.y, rc.Width(), rc.Height(),
vw->m_MemDC, 0, 0, SRCCOPY);
vw->m_MemDC.SetViewportOrg(pt2);
if (0)
{ // Progress lijntje
// We kunnen rustig rechtstreeks op m_hDCOriginal tekenen want
// er komt toch nog een definitieve bitmap overheen
CPen p;
p.CreatePen(PS_SOLID ,0, RGB(128,128,128));
HPEN pOld = (HPEN)SelectObject(vw->m_hDCOriginal, p);
CPoint org;
MoveToEx(vw->m_hDCOriginal, 1, 0, &org);
LineTo(vw->m_hDCOriginal, 1, (int)(progress*rc.Height()));
MoveToEx(vw->m_hDCOriginal, org.x, org.y, NULL);
SelectObject(vw->m_hDCOriginal, pOld);
}
::SetViewportExtEx(vw->m_hDCOriginal, orgSize.cx, orgSize.cy, NULL);
vw->m_Timer = GetTickCount();
}
return TRUE; // Continue
};
void CSLNKDwfViewerView::DoPaint(CDCHandle dc)
{
if (m_dwfPath == "")
{
DoMessage(dc, "Open DWF first");
return;
}
// Altijd 10% van ons beeld zoomen met scrollbars
CRect rc;
GetClientRect(rc);
SetScrollLine(max(rc.Size().cx / GetZoomScale() / 10 + 0.5, 1),
max(rc.Size().cy / GetZoomScale() / 10 + 0.5, 1));
// Default 0.5% inzoomen
CSize wSize;
dc.GetViewportExt(&wSize);
#if 0
CPoint pOrg;
dc.GetViewportOrg(&pOrg);
pOrg.x += MulDiv(wSize.cx, 1, 200); // Half verschuiven
pOrg.y += MulDiv(wSize.cy, 1, 200);
dc.SetViewportOrg(pOrg);
wSize.cx = MulDiv(wSize.cx, 198, 200);
wSize.cy = MulDiv(wSize.cy, 198, 200);
#endif
CWaitCursor Wait;
if (0&&GetZoomScale() != 1.0)
::PaintToDC(dc, m_dwfPath, m_nPage, m_iWhip2DC, wSize);
else
{
CPoint pt;
dc.GetViewportOrg(&pt);
if (m_Bitmap == NULL ||
m_BitmapViewportOrigin != pt ||
m_BitmapViewportExt != wSize ||
m_BitmapClientRect != rc)
{ // Bitmap opnieuw maken
if (m_Bitmap != NULL) delete m_Bitmap;
CBitmapHandle pOldBitmap;
m_MemDC.CreateCompatibleDC(dc);
// Create a bitmap big enough to hold the window's image
m_Bitmap = new CBitmap;
m_Bitmap->CreateCompatibleBitmap(dc, rc.Width(), rc.Height());
m_MemDC.SetViewportOrg(pt.x, pt.y);
pOldBitmap = m_MemDC.SelectBitmap(*m_Bitmap);
m_Timer = GetTickCount();
m_hDCOriginal = dc; // Hier gaan we wel progress op tekenen
m_iWhip2DC.set_progress_action(my_progress_action, (void *) this);
{
LARGE_INTEGER currTime;
LARGE_INTEGER endTime;
LARGE_INTEGER frequency;
if (!QueryPerformanceCounter(&currTime))
return;
if (!QueryPerformanceFrequency(&frequency))
return;
double tmStart = ((double)currTime.QuadPart)*1000/frequency.QuadPart;
::PaintToDC(m_MemDC, m_dwfPath, m_nPage, m_iWhip2DC, wSize);
if (!QueryPerformanceCounter(&endTime))
return;
if (!QueryPerformanceCounter(&currTime))
return;
double tmEnd = ((double)currTime.QuadPart)*1000/frequency.QuadPart;
// En nu?
//LPCTSTR lpszMessage = _T("Hello, World");
//::SendMessage(m_hWndStatusBar, SB_SETTEXT, 0, LPARAM(lpszMessage));
CString s;
s.Format("Klaar in %.0lf ms", tmEnd - tmStart);
m_Parent.m_status.SetText(0, s);
}
// Select the original bitmap back in
m_MemDC.SelectBitmap(pOldBitmap);
m_MemDC.DeleteDC();
m_BitmapViewportOrigin = pt;
m_BitmapViewportExt = wSize;
m_BitmapClientRect = rc;
}
// Nu het echt tonen
{
CBitmapHandle pOldBitmap;
CDC MemDC;
// And a memory DC, set Map Mode
MemDC.CreateCompatibleDC(dc);
pOldBitmap = MemDC.SelectBitmap(*m_Bitmap);
dc.SetViewportExt(rc.Size());
dc.BitBlt( -pt.x, -pt.y, rc.Width(), rc.Height(), MemDC, 0, 0, SRCCOPY );
MemDC.SelectBitmap(pOldBitmap);
MemDC.DeleteDC();
}
}
return;
}
void CSLNKDwfViewerView::SetPage(int nPage)
{
m_nPage = nPage;
if (m_Bitmap != NULL)
{
delete m_Bitmap; // It is dirty
m_Bitmap = NULL;
}
CRect rc;
GetClientRect(&rc);
SetScrollSize(rc.Width()*SCL, rc.Height()*SCL);
SetScrollLine(0, 0);
SetZoomScaleMin(.5 / SCL);
Zoom(1 / SCL);
SetScrollLine(rc.Width() / SCL, rc.Height() / SCL);
};
LRESULT CSLNKDwfViewerView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CZoomScrollWindowImpl::OnSize(uMsg, wParam, lParam, bHandled);
int cx = GET_X_LPARAM(lParam);
int cy = GET_Y_LPARAM(lParam);
CRect rc;
GetClientRect(&rc);
if (rc.Width()>0 && rc.Height()>0)
SetScrollSize(rc.Width()*SCL, rc.Height()*SCL);
return 1;
}
LRESULT CSLNKDwfViewerView::OnMouseWheel(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
int zDelta = (int)(short)HIWORD(wParam);
int fwKeys = (int)(short)LOWORD(wParam);
CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
ScreenToClient(&pt);
double delta = (fwKeys&MK_SHIFT)?0.1:(fwKeys&MK_CONTROL)?0.01:1.0;
double zoom = zDelta / WHEEL_DELTA;
if(zDelta > 0)
zoom = zoom * (1+ GetZoomDelta()*delta);
else
zoom = abs(zoom) / (1+ GetZoomDelta()*delta);
CRect rc;
GetClientRect(&rc);
CPoint newcenter(pt.x + (rc.right / 2.0 - pt.x) / zoom + 0.5,
pt.y + (rc.bottom / 2.0 - pt.y) / zoom + 0.5);
Zoom(newcenter, GetZoomScale() * zoom);
NotifyParentZoomChanged();
return 0;
}
LRESULT CSLNKDwfViewerView::OnRButtonDown(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
m_PanTotal = CPoint(0, 0);
m_PanStartPoint = point;
GetScrollOffset(m_PanStartScroll);
SetCapture(); // Zo kunnen we ook "buiten" het venster doorpannen
m_busyPanning = TRUE;
// tPanStart = GetTickCount();
bHandled = FALSE;
return 0;
}
LRESULT CSLNKDwfViewerView::OnRButtonUp(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_busyPanning)
{
ReleaseCapture();
m_busyPanning = FALSE;
// Invalidate(); // Als meer dan 1/10 seconde is nog niet alles getekend
}
bHandled = FALSE;
return 0;
}
LRESULT CSLNKDwfViewerView::OnMouseMove(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_busyPanning && (wParam & MK_RBUTTON)) // Pannen
{
POINT point = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
CPoint traveled = m_PanStartPoint - point;
m_PanTotal += traveled;
// SetCursor(::LoadCursor(AfxGetResourceHandle(), MAKEINTRESOURCE(IDC_HANDJE)));
SetScrollOffset(m_PanStartScroll + traveled);
m_PanStartPoint = point;
GetScrollOffset(m_PanStartScroll);
}
bHandled = FALSE;
return 0;
}