root / trunk / win / Cadview.cpp

Revision 724, 26.8 kB (checked in by Leo, 7 months ago)

Small cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// CADView.cpp : implementation of the CCADView class
2//
3
4#include "lc_global.h"
5#include <windowsx.h>
6#include "LeoCAD.h"
7
8#include "CADDoc.h"
9#include "CADView.h"
10#include "WheelWnd.h"
11#include "Tools.h"
12#include "PrevView.h"
13#include "project.h"
14#include "globals.h"
15#include "system.h"
16#include "view.h"
17#include "MainFrm.h"
18#include "PiecePrv.h"
19#include "lc_application.h"
20#include "lc_camera.h"
21
22#ifdef _DEBUG
23#define new DEBUG_NEW
24#undef THIS_FILE
25static char THIS_FILE[] = __FILE__;
26#endif
27
28BOOL GLWindowPreTranslateMessage (GLWindow *wnd, MSG *pMsg);
29
30/////////////////////////////////////////////////////////////////////////////
31// CCADView
32
33IMPLEMENT_DYNCREATE(CCADView, CView)
34
35BEGIN_MESSAGE_MAP(CCADView, CView)
36    //{{AFX_MSG_MAP(CCADView)
37    ON_WM_CREATE()
38    ON_WM_DESTROY()
39    ON_WM_SETCURSOR()
40    ON_WM_CAPTURECHANGED()
41    ON_WM_KEYDOWN()
42    ON_WM_KEYUP()
43    ON_WM_MOUSEWHEEL()
44    ON_WM_MBUTTONDOWN()
45    ON_WM_TIMER()
46    ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
47    //}}AFX_MSG_MAP
48    // Standard printing commands
49    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
50    ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
51    ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnDropDown)
52    ON_MESSAGE(WM_LC_SET_STEP, OnSetStep)
53    ON_MESSAGE(WM_LC_WHEEL_PAN, OnAutoPan)
54    ON_MESSAGE(WM_LC_SET_CURSOR, OnChangeCursor)
55END_MESSAGE_MAP()
56
57/////////////////////////////////////////////////////////////////////////////
58// CCADView construction/destruction
59
60CCADView::CCADView()
61{
62    m_hCursor = NULL;
63  m_pView = NULL;
64}
65
66CCADView::~CCADView()
67{
68}
69
70BOOL CCADView::PreCreateWindow(CREATESTRUCT& cs)
71{
72#define CUSTOM_CLASSNAME _T("LeoCADOpenGLClass")
73
74    cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
75
76    // call base class PreCreateWindow to get the cs.lpszClass filled in with the MFC default class name
77    if(!CView::PreCreateWindow(cs))
78        return 0;
79
80    // Register the window class if it has not already been registered.
81    WNDCLASS wndcls;
82    HINSTANCE hInst = AfxGetInstanceHandle();
83
84    // check if our class is registered
85    if(!(::GetClassInfo(hInst, CUSTOM_CLASSNAME, &wndcls)))
86    {
87        // get default MFC class settings
88        if(::GetClassInfo(hInst, cs.lpszClass, &wndcls))
89        {
90            // set our class name
91            wndcls.lpszClassName = CUSTOM_CLASSNAME;
92
93            // change settings for your custom class
94            wndcls.style |= CS_OWNDC;
95            wndcls.hbrBackground = NULL;
96
97            // register class
98            if (!AfxRegisterClass(&wndcls))
99                AfxThrowResourceException();
100        }
101        else
102            AfxThrowResourceException();
103    }
104
105    // set our class name in CREATESTRUCT
106    cs.lpszClass = CUSTOM_CLASSNAME;
107
108    return 1;                                                   // we're all set
109}
110
111/////////////////////////////////////////////////////////////////////////////
112// CCADView drawing
113
114void CCADView::OnDraw(CDC* /*pDC*/)
115{
116}
117
118/////////////////////////////////////////////////////////////////////////////
119// CCADView printing
120
121// Derived to use our version of the toolbar
122void CCADView::OnFilePrintPreview()
123{
124    // In derived classes, implement special window handling here
125    // Be sure to Unhook Frame Window close if hooked.
126
127    // must not create this on the frame.  Must outlive this function
128    CPrintPreviewState* pState = new CPrintPreviewState;
129    pState->lpfnCloseProc = _AfxPreviewCloseProcEx;
130
131    // DoPrintPreview's return value does not necessarily indicate that
132    // Print preview succeeded or failed, but rather what actions are necessary
133    // at this point.  If DoPrintPreview returns TRUE, it means that
134    // OnEndPrintPreview will be (or has already been) called and the
135    // pState structure will be/has been deleted.
136    // If DoPrintPreview returns FALSE, it means that OnEndPrintPreview
137    // WILL NOT be called and that cleanup, including deleting pState
138    // must be done here.
139
140    if (!DoPrintPreview(IDR_PREVIEW, this,
141            RUNTIME_CLASS(CPreviewViewEx), pState))
142    {
143        // In derived classes, reverse special window handling here for
144        // Preview failure case
145
146        TRACE0("Error: DoPrintPreview failed.\n");
147        AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
148        delete pState;      // preview failed to initialize, delete State now
149    }
150}
151
152BOOL CCADView::OnPreparePrinting(CPrintInfo* pInfo)
153{
154    pInfo->m_pPD->m_pd.nMinPage = 1;
155    pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
156    pInfo->m_pPD->m_pd.Flags |= PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOSELECTION | PD_ENABLEPRINTHOOK;
157    pInfo->m_pPD->m_pd.lpfnPrintHook = PrintHookProc;
158    pInfo->m_pPD->m_pd.lCustData = (LONG)AfxGetMainWnd();
159
160    int cols = theApp.GetProfileInt("Default", "Print Columns", 1);
161    int rows = theApp.GetProfileInt("Default", "Print Rows", 1);
162    int Max = (lcGetActiveProject()->GetLastStep()/(rows*cols));
163    if (lcGetActiveProject()->GetLastStep()%(rows*cols) != 0)
164        Max++;
165    pInfo->SetMaxPage(Max);
166
167    if (pInfo->m_bPreview)
168    {
169        CFrameWnd* pFrame = (CFrameWnd*)AfxGetMainWnd();
170
171        POSITION pos = pFrame->m_listControlBars.GetHeadPosition();
172        while (pos != NULL)
173        {
174            CControlBar* pBar = (CControlBar*)pFrame->m_listControlBars.GetNext(pos);
175            CString str;
176            pBar->GetWindowText(str);
177            if (str == _T("Full Screen"))
178            {
179                AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
180                break;
181            }
182        }
183    }
184
185    return DoPreparePrinting(pInfo);
186}
187
188void CCADView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* pInfo)
189{
190    int cols = theApp.GetProfileInt("Default", "Print Columns", 1);
191    int rows = theApp.GetProfileInt("Default", "Print Rows", 1);
192    int Max = (lcGetActiveProject()->GetLastStep()/(rows*cols));
193    if (lcGetActiveProject()->GetLastStep()%(rows*cols) != 0)
194        Max++;
195    pInfo->SetMaxPage(Max);
196}
197
198void CCADView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
199{
200    int cols = theApp.GetProfileInt("Default","Print Columns", 1);
201    int rows = theApp.GetProfileInt("Default","Print Rows", 1);
202    Project* project = lcGetActiveProject();
203
204    if (rows < 1) rows = 1;
205    if (cols < 1) cols = 1;
206    CRect rc(0, 0, pDC->GetDeviceCaps(HORZRES), pDC->GetDeviceCaps(VERTRES));
207    pDC->DPtoLP(&rc);
208    int lpx = pDC->GetDeviceCaps(LOGPIXELSX);
209    int lpy = pDC->GetDeviceCaps(LOGPIXELSY);
210    rc.DeflateRect(lpx*theApp.GetProfileInt("Default","Margin Left", 50)/100,
211        lpy*theApp.GetProfileInt("Default","Margin Top", 50)/100,
212        lpx*theApp.GetProfileInt("Default","Margin Right", 50)/100,
213        lpy*theApp.GetProfileInt("Default","Margin Bottom", 50)/100);
214
215    int w = rc.Width()/cols, h = rc.Height()/rows; // cell size
216    float viewaspect = (float)m_pView->GetWidth ()/(float)m_pView->GetHeight ();
217    int pw = w, ph = h; // picture
218    int mx = 0, my = 0; // offset
219
220    if (w < h)
221    {
222        ph = (int) (w / viewaspect);
223        my = (h - ph)/2;
224    }
225    else
226    {
227        pw = (int) (h * viewaspect);
228        mx = (w - pw)/2;
229    }
230
231    int tw = pw, th = ph; // tile size
232
233    if (tw > 1024 || th > 1024)
234        tw = th = 1024;
235
236    HDC hMemDC = CreateCompatibleDC(GetDC()->m_hDC);
237    LPBITMAPINFOHEADER lpbi;
238
239    // Preparing bitmap header for DIB section
240    BITMAPINFO bi;
241    ZeroMemory(&bi, sizeof(BITMAPINFO));
242    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
243    bi.bmiHeader.biWidth = tw;
244    bi.bmiHeader.biHeight = th;
245    bi.bmiHeader.biPlanes = 1;
246    bi.bmiHeader.biBitCount = 24;
247    bi.bmiHeader.biCompression = BI_RGB;
248    bi.bmiHeader.biSizeImage = tw * th * 3;
249    bi.bmiHeader.biXPelsPerMeter = 2925;
250    bi.bmiHeader.biYPelsPerMeter = 2925;
251   
252  HBITMAP hBm = CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, (void **)&lpbi, NULL, (DWORD)0);
253    HBITMAP hBmOld = (HBITMAP)SelectObject(hMemDC, hBm);
254
255    // Setting up a Pixel format for the DIB surface
256    PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),
257            1,PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI,
258            PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
259            0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };
260    int pixelformat = OpenGLChoosePixelFormat(hMemDC, &pfd);
261    OpenGLDescribePixelFormat (hMemDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
262    OpenGLSetPixelFormat (hMemDC, pixelformat, &pfd);
263   
264    // Creating OpenGL context
265  HGLRC hmemrc = pfnwglCreateContext(hMemDC);
266    pfnwglMakeCurrent(hMemDC, hmemrc);
267//  if (!pfnwglShareLists(m_hglRC, hmemrc))
268//      pDoc->RebuildDisplayLists(TRUE);
269    project->RenderInitialize();
270
271    LOGFONT lf;
272    memset(&lf, 0, sizeof(LOGFONT));
273    lf.lfHeight = -MulDiv(50, pDC->GetDeviceCaps(LOGPIXELSY), 72);
274    lf.lfWeight = FW_BOLD;
275    lf.lfCharSet = DEFAULT_CHARSET;
276    lf.lfQuality = PROOF_QUALITY;
277    strcpy (lf.lfFaceName , "Arial");
278    HFONT font = CreateFontIndirect(&lf);
279    HFONT OldFont = (HFONT)SelectObject(pDC->m_hDC, font);
280    pDC->SetTextAlign(TA_BASELINE|TA_CENTER|TA_NOUPDATECP);
281    float* bg = project->GetBackgroundColor();
282    pDC->SetTextColor(RGB (1.0f - bg[0], 1.0f - bg[1], 1.0f - bg[2]));
283    pDC->SetBkMode(TRANSPARENT);
284    HPEN hpOld = (HPEN)SelectObject(pDC->m_hDC,(HPEN)GetStockObject(BLACK_PEN));
285
286    u32 OldTime = project->GetCurrentTime();
287    UINT nRenderTime = 1+((pInfo->m_nCurPage-1)*rows*cols);
288
289    View view(project, NULL);
290    view.OnSize(tw, th);
291    view.SetCamera(project->GetActiveModel()->GetCamera(LC_CAMERA_MAIN));
292
293    for (int r = 0; r < rows; r++)
294    for (int c = 0; c < cols; c++)
295    {
296        if (nRenderTime > project->GetLastStep())
297            continue;
298        project->m_ActiveModel->m_CurFrame = nRenderTime;
299        project->CalculateStep();
300        FillRect(hMemDC, CRect(0,th,tw,0), (HBRUSH)GetStockObject(WHITE_BRUSH));
301
302        // Tile rendering
303        if (tw != pw)
304        {
305            lcCamera* Camera = view.GetCamera();
306
307            int CurrentTile = 0;
308            int TileWidth = tw;
309            int TileHeight = th;
310            int ImageWidth = pw;
311            int ImageHeight = ph;
312            int Columns = (ImageWidth + TileWidth - 1) / TileWidth;
313            int Rows = (ImageHeight + TileHeight - 1) / TileHeight;
314            float xmin, xmax, ymin, ymax;
315            ymax = Camera->m_NearDist * tan(Camera->m_FOV * 3.14159265f / 360.0f);
316            ymin = -ymax;
317            xmin = ymin * viewaspect;
318            xmax = ymax * viewaspect;
319
320            for (;;)
321            {
322                int CurrentTileWidth, CurrentTileHeight;
323
324                // which tile (by row and column) we're about to render
325                int CurrentRow = CurrentTile / Columns;
326                int CurrentColumn = CurrentTile % Columns;
327
328                // Compute actual size of this tile with border
329                if (CurrentRow < Rows-1)
330                    CurrentTileHeight = TileHeight;
331                else
332                    CurrentTileHeight = ImageHeight - (Rows-1) * (TileHeight);
333               
334                if (CurrentColumn < Columns-1)
335                    CurrentTileWidth = TileWidth;
336                else
337                    CurrentTileWidth = ImageWidth - (Columns-1) * (TileWidth);
338   
339                glViewport(0, 0, CurrentTileWidth, CurrentTileHeight);
340
341                project->RenderBackground(&view);
342
343                float left, right, bottom, top;
344
345                glMatrixMode(GL_PROJECTION);
346                glLoadIdentity();
347
348                // Compute projection parameters.
349                left = xmin + (xmax - xmin) * (CurrentColumn * TileWidth) / ImageWidth;
350                right = left + (xmax - xmin) * CurrentTileWidth / ImageWidth;
351                bottom = ymin + (ymax - ymin) * (CurrentRow * TileHeight) / ImageHeight;
352                top = bottom + (ymax - ymin) * CurrentTileHeight / ImageHeight;
353
354                glFrustum(left, right, bottom, top, Camera->m_NearDist, Camera->m_FarDist);
355
356                glMatrixMode(GL_MODELVIEW);
357                glLoadMatrixf(view.GetCamera()->m_WorldView);
358
359                project->RenderScene(&view);
360                glFinish();
361
362                int ctw = CurrentTileWidth;
363                int cth = CurrentTileHeight;
364                int tr = Rows - CurrentRow - 1;
365                int tc = CurrentColumn;
366
367                lpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24));
368   
369                BITMAPINFO bi;
370                ZeroMemory(&bi, sizeof(BITMAPINFO));
371                memcpy (&bi.bmiHeader, lpbi, sizeof(BITMAPINFOHEADER));
372
373                pDC->SetStretchBltMode(COLORONCOLOR);
374                StretchDIBits(pDC->m_hDC, rc.left+1+(w*c)+mx + tc*tw, rc.top+1+(h*r)+my + tr*th+th-cth, ctw, cth, 0, 0, ctw, cth,
375                    (LPBYTE) lpbi + lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY);
376                if (lpbi) GlobalFreePtr(lpbi);
377
378                // Increment tile counter.
379                CurrentTile++;
380                if (CurrentTile >= Rows * Columns)
381                    break;
382            }
383        }
384        else
385        {
386            project->Render(&view, false, false);
387            glFinish();
388            lpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24));
389           
390            BITMAPINFO bi;
391            ZeroMemory(&bi, sizeof(BITMAPINFO));
392            memcpy (&bi.bmiHeader, lpbi, sizeof(BITMAPINFOHEADER));
393            pDC->SetStretchBltMode(COLORONCOLOR);
394            StretchDIBits(pDC->m_hDC, rc.left+1+(w*c)+mx, rc.top+1+(h*r)+my, w-(2*mx), h-(2*my), 0, 0, pw, ph,
395                (LPBYTE) lpbi + lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY);
396            if (lpbi) GlobalFreePtr(lpbi);
397        }
398
399        DWORD dwPrint = theApp.GetProfileInt("Settings","Print", PRINT_NUMBERS|PRINT_BORDER);
400        if (dwPrint & PRINT_NUMBERS)
401        {
402            char tmp[4];
403            sprintf (tmp, "%d", nRenderTime);
404
405            CRect rcNumber (rc);
406            rcNumber.left += (w*c)+(int)(pDC->GetDeviceCaps (LOGPIXELSX)/2);
407            rcNumber.top += (h*r)+(int)(pDC->GetDeviceCaps (LOGPIXELSY)/2);
408
409            pDC->SetTextAlign (TA_TOP|TA_LEFT|TA_NOUPDATECP);
410            pDC->DrawText(tmp, strlen (tmp), rcNumber, DT_LEFT|DT_TOP|DT_SINGLELINE);
411        }
412
413        if (dwPrint & PRINT_BORDER)
414        {
415            if (r == 0)
416            {
417                pDC->MoveTo(rc.left+(w*c), rc.top+(h*r));
418                pDC->LineTo(rc.left+(w*(c+1)), rc.top+(h*r));
419            }
420            if (c == 0)
421            {
422                pDC->MoveTo(rc.left+(w*c), rc.top+(h*r));
423                pDC->LineTo(rc.left+(w*c), rc.top+(h*(r+1)));
424            }
425           
426            pDC->MoveTo(rc.left+(w*(c+1)), rc.top+(h*r));
427            pDC->LineTo(rc.left+(w*(c+1)), rc.top+(h*(r+1)));
428            pDC->MoveTo(rc.left+(w*c), rc.top+(h*(r+1)));
429            pDC->LineTo(rc.left+(w*(c+1)), rc.top+(h*(r+1)));
430        }
431        nRenderTime++;
432    }
433
434    project->m_ActiveModel->m_CurFrame = OldTime;
435
436    pfnwglMakeCurrent(NULL, NULL);
437    pfnwglDeleteContext(hmemrc);
438    SelectObject(hMemDC, hBmOld);
439    DeleteObject(hBm);
440    DeleteDC(hMemDC);
441
442    SelectObject(pDC->m_hDC, hpOld);
443    SelectObject(pDC->m_hDC, OldFont);
444    DeleteObject(font);
445    glFinish();
446
447    lf.lfHeight = -MulDiv(12, pDC->GetDeviceCaps(LOGPIXELSY), 72);
448    lf.lfWeight = FW_REGULAR;
449    font = CreateFontIndirect(&lf);
450    OldFont = (HFONT)SelectObject(pDC->m_hDC, font);
451    pDC->SetTextColor(RGB (0,0,0));
452    pDC->SetTextAlign (TA_TOP|TA_LEFT|TA_NOUPDATECP);
453    rc.top -= pDC->GetDeviceCaps(LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Top", 50)/200;
454    rc.bottom += pDC->GetDeviceCaps(LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Bottom", 50)/200;
455    PrintHeader(FALSE, pDC->GetSafeHdc(), rc, pInfo->m_nCurPage, pInfo->GetMaxPage(), FALSE);
456    PrintHeader(TRUE, pDC->GetSafeHdc(), rc, pInfo->m_nCurPage, pInfo->GetMaxPage(), FALSE);
457    SelectObject(pDC->m_hDC, OldFont);
458    DeleteObject(font);
459}
460
461void CCADView::PrintHeader(BOOL bFooter, HDC hDC, CRect rc, UINT nCurPage, UINT nMaxPage, BOOL bCatalog)
462{
463    Project* project = lcGetActiveProject();
464    CString str,tmp;
465    UINT nFormat = DT_CENTER;
466    int r;
467
468    if (bFooter)
469        str = project->m_strFooter;
470    else
471        str = project->m_strHeader;
472
473    if (str.GetLength())
474    {
475        while ((r = str.Find("&L")) != -1)
476        {
477            nFormat = DT_LEFT;
478            tmp = str.Left (r);
479            tmp += str.Right(str.GetLength()-r-2);
480            str = tmp;
481        }
482        while ((r = str.Find("&C")) != -1)
483        {
484            nFormat = DT_CENTER;
485            tmp = str.Left (r);
486            tmp += str.Right(str.GetLength()-r-2);
487            str = tmp;
488        }
489        while ((r = str.Find("&R")) != -1)
490        {
491            nFormat = DT_RIGHT;
492            tmp = str.Left (r);
493            tmp += str.Right(str.GetLength()-r-2);
494            str = tmp;
495        }
496        while ((r = str.Find("&F")) != -1)
497        {
498            tmp = str.Left (r);
499            if (bCatalog)
500                tmp += "LeoCAD Pieces Catalog";
501            else
502                tmp += project->m_strTitle;
503            tmp += str.Right(str.GetLength()-r-2);
504            str = tmp;
505        }
506        while ((r = str.Find("&A")) != -1)
507        {
508            tmp = str.Left (r);
509            tmp += project->m_ActiveModel->m_Author;
510            tmp += str.Right(str.GetLength()-r-2);
511            str = tmp;
512        }
513        while ((r = str.Find("&N")) != -1)
514        {
515            tmp = str.Left (r);
516            tmp += project->m_ActiveModel->m_Description;
517            tmp += str.Right(str.GetLength()-r-2);
518            str = tmp;
519        }
520        while ((r = str.Find("&D")) != -1)
521        {
522            char dbuffer [9];
523            _strdate( dbuffer );
524            tmp = str.Left (r);
525            tmp += dbuffer;
526            tmp += str.Right(str.GetLength()-r-2);
527            str = tmp;
528        }
529        while ((r = str.Find("&T")) != -1)
530        {
531            char tbuffer [9];
532            _strtime( tbuffer );
533            tmp = str.Left (r);
534            tmp += tbuffer;
535            tmp += str.Right(str.GetLength()-r-2);
536            str = tmp;
537        }
538        while ((r = str.Find("&P")) != -1)
539        {
540            char buf[5];
541            sprintf (buf, "%d", nCurPage);
542            tmp = str.Left (r);
543            tmp += buf;
544            tmp += str.Right(str.GetLength()-r-2);
545            str = tmp;
546        }
547        while ((r = str.Find("&O")) != -1)
548        {
549            char buf[5];
550            sprintf (buf, "%d", nMaxPage);
551            tmp = str.Left (r);
552            tmp += buf;
553            tmp += str.Right(str.GetLength()-r-2);
554            str = tmp;
555        }
556    }
557
558    if (bFooter)
559        nFormat |= DT_BOTTOM|DT_SINGLELINE;
560    else
561        nFormat |= DT_TOP|DT_SINGLELINE;
562
563    DrawText(hDC, (LPCTSTR)str, str.GetLength(), rc, nFormat);
564}
565
566void CCADView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
567{
568}
569
570void CCADView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewViewEx* pView)
571{
572//  CView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT, CPreviewView* pView)
573    ASSERT_VALID(pDC);
574    ASSERT_VALID(pView);
575
576    if (pView->m_pPrintView != NULL)
577        pView->m_pPrintView->OnEndPrinting(pDC, pInfo);
578
579    CFrameWnd* pParent;
580    CWnd* pNaturalParent = pView->GetParentFrame();
581    pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
582    if (pParent == NULL || pParent->IsIconic())
583        pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
584
585    ASSERT_VALID(pParent);
586    ASSERT_KINDOF(CFrameWnd, pParent);
587
588    // restore the old main window
589    pParent->OnSetPreviewMode(FALSE, pView->m_pPreviewState);
590
591    // Force active view back to old one
592    pParent->SetActiveView(pView->m_pPreviewState->pViewActiveOld);
593    if (pParent != GetParentFrame())
594        OnActivateView(TRUE, this, this);   // re-activate view in real frame
595    pView->DestroyWindow();     // destroy preview view
596            // C++ object will be deleted in PostNcDestroy
597
598    // restore main frame layout and idle message
599    pParent->RecalcLayout();
600    pParent->SendMessage(WM_SETMESSAGESTRING, (WPARAM)AFX_IDS_IDLEMESSAGE, 0L);
601    pParent->UpdateWindow();
602
603    InvalidateRect(NULL, FALSE);
604}
605
606BOOL CCADView::DoPrintPreview(UINT nIDResource, CView* pPrintView, CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
607{
608    ASSERT_VALID_IDR(nIDResource);
609    ASSERT_VALID(pPrintView);
610    ASSERT(pPreviewViewClass != NULL);
611    ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewViewEx)));
612    ASSERT(pState != NULL);
613
614    CFrameWnd* pParent;
615    CWnd* pNaturalParent = pPrintView->GetParentFrame();
616    pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
617    if (pParent == NULL || pParent->IsIconic())
618        pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
619
620    ASSERT_VALID(pParent);
621    ASSERT_KINDOF(CFrameWnd, pParent);
622
623    CCreateContext context;
624    context.m_pCurrentFrame = pParent;
625    context.m_pCurrentDoc = GetDocument();
626    context.m_pLastView = this;
627
628    // Create the preview view object
629    CPreviewViewEx* pView = (CPreviewViewEx*)pPreviewViewClass->CreateObject();
630    if (pView == NULL)
631    {
632        TRACE0("Error: Failed to create preview view.\n");
633        return FALSE;
634    }
635    ASSERT_KINDOF(CPreviewViewEx, pView);
636    pView->m_pPreviewState = pState;        // save pointer
637
638    pParent->OnSetPreviewMode(TRUE, pState);    // Take over Frame Window
639
640    // Create the toolbar from the dialog resource
641    pView->m_pToolBar = new CFlatToolBar;
642
643    if (!pView->m_pToolBar->Create(pParent, WS_CHILD | WS_VISIBLE | CBRS_TOP, AFX_IDW_PREVIEW_BAR) ||
644        !pView->m_pToolBar->LoadToolBar(nIDResource))
645    {
646        TRACE0("Error: Preview could not create toolbar.\n");
647        pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
648        delete pView->m_pToolBar;       // not autodestruct yet
649        pView->m_pToolBar = NULL;
650        pView->m_pPreviewState = NULL;  // do not delete state structure
651        delete pView;
652        return FALSE;
653    }
654    pView->m_pToolBar->SetBarStyle(pView->m_pToolBar->GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
655
656/*
657    pView->m_pToolBar = new CDialogBar;
658    if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),
659        CBRS_TOP, AFX_IDW_PREVIEW_BAR))
660    {
661        TRACE0("Error: Preview could not create toolbar dialog.\n");
662        pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
663        delete pView->m_pToolBar;       // not autodestruct yet
664        pView->m_pToolBar = NULL;
665        pView->m_pPreviewState = NULL;  // do not delete state structure
666        delete pView;
667        return FALSE;
668    }
669*/  pView->m_pToolBar->m_bAutoDelete = TRUE;    // automatic cleanup
670
671    // Create the preview view as a child of the App Main Window.  This
672    // is a sibling of this view if this is an SDI app.  This is NOT a sibling
673    // if this is an MDI app.
674
675    if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
676        CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context))
677    {
678        TRACE0("Error: couldn't create preview view for frame.\n");
679        pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
680        pView->m_pPreviewState = NULL;  // do not delete state structure
681        delete pView;
682        return FALSE;
683    }
684
685    // Preview window shown now
686
687    pState->pViewActiveOld = pParent->GetActiveView();
688    CCADView* pActiveView = (CCADView*)pParent->GetActiveFrame()->GetActiveView();
689    if (pActiveView != NULL)
690        pActiveView->OnActivateView(FALSE, pActiveView, pActiveView);
691
692    if (!pView->SetPrintView((CCADView*)pPrintView))
693    {
694        pView->OnPreviewClose();
695        return TRUE;            // signal that OnEndPrintPreview was called
696    }
697
698    pParent->SetActiveView(pView);  // set active view - even for MDI
699
700    // update toolbar and redraw everything
701    pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
702    pParent->RecalcLayout();            // position and size everything
703    pParent->UpdateWindow();
704
705    return TRUE;
706}
707
708/////////////////////////////////////////////////////////////////////////////
709// CCADView diagnostics
710
711#ifdef _DEBUG
712void CCADView::AssertValid() const
713{
714    CView::AssertValid();
715}
716
717void CCADView::Dump(CDumpContext& dc) const
718{
719    CView::Dump(dc);
720}
721
722CCADDoc* CCADView::GetDocument() // non-debug version is inline
723{
724    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCADDoc)));
725    return (CCADDoc*)m_pDocument;
726}
727#endif //_DEBUG
728
729/////////////////////////////////////////////////////////////////////////////
730// CCADView message handlers
731
732int CCADView::OnCreate(LPCREATESTRUCT lpCreateStruct)
733{
734    if (CView::OnCreate(lpCreateStruct) == -1)
735        return -1;
736
737    Project* project = lcGetActiveProject();
738
739    m_pView = new View(project, project->GetFirstView());
740    m_pView->Create(m_hWnd);
741    m_pView->OnInitialUpdate();
742
743    CCADView* ActiveView = (CCADView*)GetParentFrame()->GetActiveView();
744    if (ActiveView)
745    {
746        m_pView->SetCamera(ActiveView->m_pView->GetCamera());
747    }
748
749    SetTimer (IDT_LC_SAVETIMER, 5000, NULL);
750
751    return 0;
752}
753
754void CCADView::OnDestroy()
755{
756    delete m_pView;
757    m_pView = NULL;
758
759    KillTimer (IDT_LC_SAVETIMER);
760
761    CView::OnDestroy();
762}
763
764void CCADView::OnDropDown (NMHDR* pNotifyStruct, LRESULT* pResult)
765{
766    NMTOOLBAR* pNMToolBar = (NMTOOLBAR*)pNotifyStruct;
767    RECT rc;
768
769    ::SendMessage(pNMToolBar->hdr.hwndFrom, TB_GETRECT, (WPARAM)pNMToolBar->iItem, (LPARAM)&rc);
770
771    CRect rect(rc);
772    rect.top = rect.bottom;
773    ::ClientToScreen(pNMToolBar->hdr.hwndFrom, &rect.TopLeft());
774
775    if (pNMToolBar->iItem == ID_SNAP_ON)
776    {
777        POINT pt = { rect.left, rect.top + 1 };
778        SystemDoPopupMenu(2, pt.x, pt.y);
779    }
780
781    if (pNMToolBar->iItem == ID_LOCK_ON)
782    {
783        POINT pt = { rect.left, rect.top + 1 };
784        SystemDoPopupMenu(8, pt.x, pt.y);
785    }
786
787    *pResult = TBDDRET_DEFAULT;
788}
789
790LONG CCADView::OnChangeCursor(UINT lParam, LONG /*wParam*/)
791{
792    UINT Cursor;
793
794    POINT pt;
795    GetCursorPos(&pt);
796    ScreenToClient(&pt);
797
798    switch (m_pView->GetCursor(pt.x, pt.y))
799    {
800        case LC_CURSOR_NONE: Cursor = NULL; break;
801        case LC_CURSOR_BRICK: Cursor = IDC_BRICK; break;
802        case LC_CURSOR_LIGHT: Cursor = IDC_LIGHT; break;
803        case LC_CURSOR_SPOTLIGHT: Cursor = IDC_SPOTLIGHT; break;
804        case LC_CURSOR_CAMERA: Cursor = IDC_CAMERA; break;
805        case LC_CURSOR_SELECT: Cursor = IDC_SELECT; break;
806        case LC_CURSOR_SELECT_GROUP: Cursor = IDC_SELECT_GROUP; break;
807        case LC_CURSOR_MOVE: Cursor = IDC_MOVE; break;
808        case LC_CURSOR_ROTATE: Cursor = IDC_ROTATE; break;
809        case LC_CURSOR_ROTATEX: Cursor = IDC_ROTX; break;
810        case LC_CURSOR_ROTATEY: Cursor = IDC_ROTY; break;
811        case LC_CURSOR_DELETE: Cursor = IDC_ERASER; break;
812        case LC_CURSOR_PAINT: Cursor = IDC_PAINT; break;
813        case LC_CURSOR_ZOOM: Cursor = IDC_ZOOM; break;
814        case LC_CURSOR_ZOOM_REGION: Cursor = IDC_ZOOM_REGION; break;
815        case LC_CURSOR_PAN: Cursor = IDC_PAN; break;
816        case LC_CURSOR_ROLL: Cursor = IDC_ROLL; break;
817        case LC_CURSOR_ROTATE_VIEW: Cursor = IDC_ANGLE; break;
818        case LC_CURSOR_ORBIT: Cursor = IDC_ORBIT; break;
819
820        default:
821            LC_ASSERT_FALSE("Unknown cursor type.");
822    }
823
824    if (Cursor)
825    {
826        m_hCursor = theApp.LoadCursor(Cursor);
827        SetCursor(m_hCursor);
828    }
829    else
830        m_hCursor = NULL;
831
832    return TRUE;
833}
834
835BOOL CCADView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
836{
837    if (CView::OnSetCursor(pWnd, nHitTest, message))
838        return TRUE;
839
840    OnChangeCursor(0, 0);
841
842    if (m_hCursor)
843    {
844        SetCursor(m_hCursor);
845        return TRUE;
846    }
847
848    return FALSE;
849}
850
851BOOL CCADView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
852{
853    if (zDelta > 0)
854        lcGetActiveProject()->HandleCommand(LC_VIEW_ZOOMOUT, 0);
855    else
856        lcGetActiveProject()->HandleCommand(LC_VIEW_ZOOMIN, 0);
857
858    return CView::OnMouseWheel(nFlags, zDelta, pt);
859}
860
861void CCADView::OnMButtonDown(UINT nFlags, CPoint point)
862{
863    BOOL bCtl = GetKeyState(VK_CONTROL) & 0x8000;
864    if(!bCtl && nFlags == MK_MBUTTON)
865    {
866        CWheelWnd *pwndPanWindow = new CWheelWnd(point);
867        if (!pwndPanWindow->Create(this))
868            delete pwndPanWindow;
869    }
870    else
871        CView::OnMButtonDown(nFlags, point);
872}
873
874// Notification from the auto-pan window
875LONG CCADView::OnAutoPan(UINT lParam, LONG wParam)
876{
877    CPoint pt1(lParam), pt2(wParam);
878    pt2 -= pt1;
879    pt2.y = -pt2.y;
880
881    unsigned long pt = ((short)pt2.x) | ((unsigned long)(((short)pt2.y) << 16));
882    lcGetActiveProject()->HandleCommand(LC_VIEW_AUTOPAN, pt);   
883
884    return TRUE;
885}
886
887void CCADView::OnTimer(UINT nIDEvent)
888{
889    if (nIDEvent == IDT_LC_SAVETIMER)
890        lcGetActiveProject()->CheckAutoSave();
891   
892    CView::OnTimer(nIDEvent);
893}
894
895// lParam -> new step/frame
896LONG CCADView::OnSetStep(UINT lParam, LONG /*wParam*/)
897{
898    if (lParam > 0)
899        lcGetActiveProject()->HandleCommand(LC_VIEW_STEP_SET, lParam);
900
901    return TRUE;
902}
903
904void CCADView::OnCaptureChanged(CWnd *pWnd)
905{
906    if (pWnd != this)
907        lcPostMessage(LC_MSG_MOUSE_CAPTURE_LOST, 0);
908   
909    CView::OnCaptureChanged(pWnd);
910}
911
912void CCADView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
913{
914    char nKey = nChar;
915
916    if (nChar >= VK_NUMPAD0 && nChar <= VK_NUMPAD9)
917    {
918        nKey = nChar - VK_NUMPAD0 + '0';
919    }
920
921    // Update cursor for multiple selection.
922    if (nChar == VK_CONTROL)
923    {
924        if (lcGetActiveProject()->GetAction() == LC_ACTION_SELECT)
925        {
926            POINT pt;
927
928            GetCursorPos(&pt);
929            CRect rc;
930            GetWindowRect(rc);
931
932            if (rc.PtInRect(pt))
933                OnSetCursor(this, HTCLIENT, 0);
934        }
935    }
936
937    lcGetActiveProject()->OnKeyDown(nKey, GetKeyState(VK_CONTROL) < 0, GetKeyState(VK_SHIFT) < 0);
938
939    CView::OnKeyDown(nChar, nRepCnt, nFlags);
940}
941
942void CCADView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
943{
944    // Update cursor for multiple selection.
945    if (nChar == VK_CONTROL)
946    {
947        if (lcGetActiveProject()->GetAction() == LC_ACTION_SELECT)
948        {
949            POINT pt;
950
951            GetCursorPos(&pt);
952            CRect rc;
953            GetWindowRect(rc);
954
955            if (rc.PtInRect(pt))
956                OnSetCursor(this, HTCLIENT, 0);
957        }
958    }
959
960    CView::OnKeyUp(nChar, nRepCnt, nFlags);
961}
962
963void CCADView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
964{
965    if (pActivateView && pActivateView->IsKindOf(RUNTIME_CLASS(CCADView)))
966        lcGetActiveProject()->SetActiveView(((CCADView*)pActivateView)->m_pView);
967    else
968        lcGetActiveProject()->SetActiveView(NULL);
969
970    CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
971}
972
973LRESULT CCADView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
974{
975    if (m_pView)
976    {
977        MSG msg;
978
979        msg.message = message;
980        msg.wParam = wParam;
981        msg.lParam = lParam;
982
983        if (GLWindowPreTranslateMessage(m_pView, &msg))
984            return TRUE;
985    }
986
987    return CView::WindowProc(message, wParam, lParam);
988}
Note: See TracBrowser for help on using the browser.