388 lines
9.9 KiB
C++
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;
|
|
}
|