c_graph.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. // c_graph.cpp
  2. // Management of the graphics window, including its menus,
  3. // COPY and PRINT operations and re-sizing.
  4. //
  5. // Copyright (C)/©/¸ Codemist Ltd, 1995-2001
  6. /*
  7. * This code may be used and modified, and redistributed in binary
  8. * or source form, subject to the "CCL Public License", which should
  9. * accompany it. This license is a variant on the BSD license, and thus
  10. * permits use of code derived from this in either open and commercial
  11. * projects: but it does require that updates to this code be made
  12. * available back to the originators of the package.
  13. * Before merging other code in with this or linking this code
  14. * with other packages or libraries please check that the license terms
  15. * of the other material are compatible with those of this.
  16. */
  17. /* Signature: 54823e70 08-Apr-2002 */
  18. #ifdef GRAPHICS_WINDOW
  19. #include "cwin.hpp"
  20. CGraphicsWindow::CGraphicsWindow()
  21. {
  22. // I want the default size for my graphics window to be something that I
  23. // control rather than something that Windows imposes upon me. So I will
  24. // start by measuring the screen and go on from there...
  25. screenWidth = ::GetSystemMetrics(SM_CXSCREEN);
  26. screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
  27. graphicsWidth = (10*screenWidth)/17;
  28. graphicsHeight = (4*graphicsWidth)/5;
  29. CRect r(rectDefault);
  30. CSize s(graphicsWidth, graphicsHeight);
  31. CPoint w = r.TopLeft();
  32. r.BottomRight() = w + s;
  33. int temp = r.right - screenWidth + 16;
  34. if (temp > 0) r.left -= temp, r.right -= temp;
  35. temp = r.bottom - screenHeight + 16;
  36. if (temp > 0) r.bottom -= temp, r.top -= temp;
  37. Create(NULL, "Graphics Window",
  38. WS_POPUP | WS_CAPTION | WS_OVERLAPPED | WS_MINIMIZEBOX |
  39. WS_MAXIMIZEBOX | WS_TABSTOP | WS_THICKFRAME,
  40. r, NULL,
  41. "GraphicsMenu");
  42. this->GetClientRect(&r);
  43. graphicsHeight = r.bottom - r.top;
  44. graphicsWidth = r.right - r.left;
  45. viewpointWindow.ShowWindow(SW_HIDE);
  46. viewpointShown = FALSE;
  47. memcpy((void *)xform, (void *)stdView, sizeof(stdView));
  48. perspecDistance = 50000.0;
  49. drawWire = 1;
  50. drawSurface = IDM_SQUARES;
  51. wirePreview = 1;
  52. fullRender = fullyRendered = 0;
  53. ctrlPressed = 0;
  54. }
  55. virtual CGraphicsWindow::~CGraphicsWindow()
  56. {
  57. DestroyWindow();
  58. }
  59. BEGIN_MESSAGE_MAP(CGraphicsWindow, CFrameWnd)
  60. ON_WM_SETFOCUS()
  61. // ON_WM_KILLFOCUS()
  62. ON_WM_SIZE()
  63. ON_WM_PAINT()
  64. ON_WM_CHAR()
  65. // ON_WM_SYSCHAR()
  66. ON_WM_KEYDOWN()
  67. ON_WM_KEYUP()
  68. // ON_WM_LBUTTONDBLCLK()
  69. // ON_WM_LBUTTONDOWN()
  70. // ON_WM_LBUTTONUP()
  71. // ON_WM_MBUTTONDBLCLK()
  72. // ON_WM_MBUTTONDOWN()
  73. // ON_WM_MBUTTONUP()
  74. // ON_WM_RBUTTONDBLCLK()
  75. // ON_WM_RBUTTONDOWN()
  76. // ON_WM_RBUTTONUP()
  77. // ON_WM_MOUSEMOVE()
  78. // ON_WM_NCLBUTTONDOWN()
  79. // ON_WM_NCMBUTTONDOWN()
  80. // ON_WM_NCRBUTTONDOWN()
  81. // Now things on the menus...
  82. ON_COMMAND(IDM_SAVEAS, OnSaveAs)
  83. ON_COMMAND(IDM_PRINT, OnPrint)
  84. ON_COMMAND(IDM_CLOSE, OnCloseButton)
  85. ON_COMMAND(IDM_COPY, OnCopy)
  86. ON_COMMAND(IDM_CLEAR, OnClear)
  87. ON_COMMAND(IDM_REDRAW, OnRedraw)
  88. ON_COMMAND(IDM_VIEWPOINT, OnViewpoint)
  89. ON_MESSAGE(WM_USER+2, OnViewpoint1)
  90. ON_COMMAND(IDM_WIREFRAME, OnWireframe)
  91. ON_COMMAND(IDM_NOSURFACE, OnNoSurface)
  92. ON_COMMAND(IDM_SURFACE, OnSurface)
  93. ON_COMMAND(IDM_SQUARES, OnSquares)
  94. ON_COMMAND(IDM_TRIANGLES, OnTriangles)
  95. ON_COMMAND(IDM_SMOOTH, OnSmooth)
  96. ON_COMMAND(IDM_HISMOOTH, OnHiSmooth)
  97. ON_COMMAND(IDM_WIREPREVIEW, OnWirePreview)
  98. ON_COMMAND(IDM_ROTLEFT, OnRotLeft)
  99. ON_COMMAND(IDM_ROTRIGHT, OnRotRight)
  100. ON_COMMAND(IDM_ROTUP, OnRotUp)
  101. ON_COMMAND(IDM_ROTDOWN, OnRotDown)
  102. ON_COMMAND(IDM_CLOCKWISE, OnClockwise)
  103. ON_COMMAND(IDM_ANTICLOCK, OnAntiClockwise)
  104. ON_COMMAND(IDM_ENLARGE, OnEnlarge)
  105. ON_COMMAND(IDM_SHRINK, OnShrink)
  106. END_MESSAGE_MAP()
  107. // Now message handlers
  108. void CGraphicsWindow::OnCloseButton()
  109. {
  110. theApp.mainWindow->PostMessage(WM_USER, 0, 0);
  111. }
  112. void CGraphicsWindow::OnSize(UINT nType, int cx, int cy)
  113. {
  114. graphicsWidth = cx;
  115. graphicsHeight = cy;
  116. Invalidate();
  117. }
  118. void CGraphicsWindow::OnPaint()
  119. {
  120. CClientDC dc(this);
  121. CRect rect;
  122. this->GetClientRect(&rect);
  123. RECT r;
  124. GetUpdateRect(&r, TRUE);
  125. // In some cases I will redraw the screen in bands, in an attempt to get
  126. // better response to further events... if I draw the whole object all at once
  127. // the re-draw can take a painfully long time during which my application is
  128. // unable to respond to anything else.
  129. if (drawSurface == IDM_SMOOTH || drawSurface == IDM_HISMOOTH)
  130. { int clientWidth = rect.right - rect.left;
  131. int left = r.left, right = r.right;
  132. int updateWidth = right - left;
  133. if (4*updateWidth > 3*clientWidth+10) r.right = (3*left + right)/4;
  134. else if (2*updateWidth > clientWidth+10) r.right = (2*left + right)/3;
  135. else if (4*updateWidth > clientWidth+10) r.right = (left + right)/2;
  136. }
  137. ValidateRect(&r);
  138. dc.IntersectClipRect(&r);
  139. PaintOrPrint(&dc, &r, graphicsWidth, graphicsHeight, NULL, NULL);
  140. dc.SelectStockObject(SYSTEM_FONT);
  141. }
  142. void CGraphicsWindow::SubTriangle(CDC *dc,
  143. int x1, int y1, int red1, int green1, int blue1,
  144. int x2, int y2, int red2, int green2, int blue2,
  145. int x3, int y3, int red3, int green3, int blue3, int n)
  146. {
  147. if (n == 0)
  148. { POINT p[3];
  149. p[0].x = x1; p[0].y = y1;
  150. p[1].x = x2; p[1].y = y2;
  151. p[2].x = x3; p[2].y = y3;
  152. CBrush b(RGB((red1+red2+red3)/3,
  153. (green1+green2+green3)/3,
  154. (blue1+blue2+blue3)/3));
  155. CBrush *oldBrush = dc->SelectObject(&b);
  156. dc->Polygon(p, 3);
  157. dc->SelectObject(oldBrush);
  158. return;
  159. }
  160. SubTriangle(dc, x1, y1, red1, green1, blue1,
  161. (x1+x2)/2, (y1+y2)/2, (red1+red2)/2, (green1+green2)/2, (blue1+blue2)/2,
  162. (x1+x3)/2, (y1+y3)/2, (red1+red3)/2, (green1+green3)/2, (blue1+blue3)/2, n-1);
  163. SubTriangle(dc, x2, y2, red2, green2, blue2,
  164. (x2+x3)/2, (y2+y3)/2, (red2+red3)/2, (green2+green3)/2, (blue2+blue3)/2,
  165. (x2+x1)/2, (y2+y1)/2, (red2+red1)/2, (green2+green1)/2, (blue2+blue1)/2, n-1);
  166. SubTriangle(dc, x3, y3, red3, green3, blue3,
  167. (x3+x1)/2, (y3+y1)/2, (red3+red1)/2, (green3+green1)/2, (blue3+blue1)/2,
  168. (x3+x2)/2, (y3+y2)/2, (red3+red2)/2, (green3+green2)/2, (blue3+blue2)/2, n-1);
  169. SubTriangle(dc, (x2+x3)/2, (y2+y3)/2, (red2+red3)/2, (green2+green3)/2, (blue2+blue3)/2,
  170. (x1+x2)/2, (y1+y2)/2, (red1+red2)/2, (green1+green2)/2, (blue1+blue2)/2,
  171. (x1+x3)/2, (y1+y3)/2, (red1+red3)/2, (green1+green3)/2, (blue1+blue3)/2, n-1);
  172. }
  173. void CGraphicsWindow::PaintOrPrint(CDC *dc, RECT *clip, int width, int height,
  174. CFont *mainFont, CFont *smallFont)
  175. {
  176. paintTriangles(dc, clip, width, height);
  177. }
  178. void CGraphicsWindow::OnSetFocus(CWnd *pOldWnd)
  179. {
  180. SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
  181. }
  182. void CGraphicsWindow::OnKillFocus(CWnd *pNewWnd)
  183. {
  184. }
  185. void CGraphicsWindow::OnChar(UINT ch, UINT nRepCnt, UINT nFlags)
  186. {
  187. switch (ch)
  188. {
  189. case ('O' & 0x1f):
  190. OnCopy();
  191. return;
  192. case ('L' & 0x1f):
  193. OnRedraw();
  194. return;
  195. default:
  196. // DisplayMsg("Char %d %x", ch, ch);
  197. return;
  198. }
  199. }
  200. //- void CGraphicsWindow::OnSysChar(UINT ch, UINT nRepCnt, UINT nFlags)
  201. //- {
  202. //- switch (ch)
  203. //- {
  204. //- default:
  205. //- DisplayMsg("SysChar %d %x", ch, ch);
  206. //- return;
  207. //- }
  208. //- }
  209. void CGraphicsWindow::OnKeyDown(UINT ch, UINT nRepCnt, UINT nFlags)
  210. {
  211. switch (ch)
  212. {
  213. case VK_SHIFT:
  214. ctrlPressed |= 1;
  215. break;
  216. case VK_CONTROL:
  217. ctrlPressed |= 2;
  218. break;
  219. // Here the direction arrows can be used to shift the object (in this case
  220. // I will always make them move the object, never the viewpoint). Just
  221. // pressed directly they give rotations. SHIFT increases the amount of
  222. // rotation applied. CONTROL and CONTROL+SHIFT give translations rather than
  223. // rotations. I do not give as fine control here as I do via the viewpoint
  224. // dialog-box, and will always fully repaint the screen after every keystroke,
  225. // which may sometimes feel clumsy.
  226. case VK_LEFT:
  227. case VK_NUMPAD4:
  228. switch (ctrlPressed & 3)
  229. {
  230. case 0: viewpointWindow.rotateXform(Yaxis, 5.625); break;
  231. case 1: viewpointWindow.rotateXform(Yaxis, 22.5); break;
  232. case 2: viewpointWindow.translateXform(500.0, 0.0); break;
  233. case 3: viewpointWindow.translateXform(2500.0, 0.0); break;
  234. }
  235. break;
  236. case VK_RIGHT:
  237. case VK_NUMPAD6:
  238. switch (ctrlPressed & 3)
  239. {
  240. case 0: viewpointWindow.rotateXform(Yaxis, -5.625); break;
  241. case 1: viewpointWindow.rotateXform(Yaxis, -22.5); break;
  242. case 2: viewpointWindow.translateXform(-500.0, 0.0); break;
  243. case 3: viewpointWindow.translateXform(-2500.0, 0.0); break;
  244. }
  245. break;
  246. case VK_UP:
  247. case VK_NUMPAD8:
  248. switch (ctrlPressed & 3)
  249. {
  250. case 0: viewpointWindow.rotateXform(Xaxis, -5.625); break;
  251. case 1: viewpointWindow.rotateXform(Xaxis, -22.5); break;
  252. case 2: viewpointWindow.translateXform(0.0, -500.0); break;
  253. case 3: viewpointWindow.translateXform(0.0, -2500.0); break;
  254. }
  255. break;
  256. case VK_DOWN:
  257. case VK_NUMPAD2:
  258. switch (ctrlPressed & 3)
  259. {
  260. case 0: viewpointWindow.rotateXform(Xaxis, 5.625); break;
  261. case 1: viewpointWindow.rotateXform(Xaxis, 22.5); break;
  262. case 2: viewpointWindow.translateXform(0.0, 500.0); break;
  263. case 3: viewpointWindow.translateXform(0.0, 2500.0); break;
  264. }
  265. break;
  266. case VK_X:
  267. viewpointWindow.resetXform(Xaxis);
  268. break;
  269. case VK_Y:
  270. viewpointWindow.resetXform(Yaxis);
  271. break;
  272. case VK_Z:
  273. viewpointWindow.resetXform(Zaxis);
  274. break;
  275. }
  276. }
  277. void CGraphicsWindow::OnKeyUp(UINT ch, UINT nRepCnt, UINT nFlags)
  278. {
  279. switch (ch)
  280. {
  281. case VK_SHIFT:
  282. ctrlPressed &= ~1;
  283. break;
  284. case VK_CONTROL:
  285. ctrlPressed &= ~2;
  286. break;
  287. }
  288. }
  289. void CGraphicsWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
  290. {
  291. }
  292. void CGraphicsWindow::OnLButtonDown(UINT nFlags, CPoint point)
  293. {
  294. }
  295. void CGraphicsWindow::OnLButtonUp(UINT nFlags, CPoint point)
  296. {
  297. }
  298. void CGraphicsWindow::OnMButtonDblClk(UINT nFlags, CPoint point)
  299. {
  300. }
  301. void CGraphicsWindow::OnMButtonDown(UINT nFlags, CPoint point)
  302. {
  303. }
  304. void CGraphicsWindow::OnMButtonUp(UINT nFlags, CPoint point)
  305. {
  306. }
  307. void CGraphicsWindow::OnRButtonDblClk(UINT nFlags, CPoint point)
  308. {
  309. }
  310. void CGraphicsWindow::OnRButtonDown(UINT nFlags, CPoint point)
  311. {
  312. }
  313. void CGraphicsWindow::OnRButtonUp(UINT nFlags, CPoint point)
  314. {
  315. }
  316. void CGraphicsWindow::OnMouseMove(UINT nFlags, CPoint point)
  317. {
  318. }
  319. void CGraphicsWindow::OnNcLButtonDown(UINT nFlags, CPoint point)
  320. {
  321. }
  322. void CGraphicsWindow::OnNcMButtonDown(UINT nFlags, CPoint point)
  323. {
  324. }
  325. void CGraphicsWindow::OnNcRButtonDown(UINT nFlags, CPoint point)
  326. {
  327. }
  328. //
  329. // Now the things provoked from the menus...
  330. //
  331. HGLOBAL CGraphicsWindow::PaintBitmap(int *size, int *ppsize)
  332. {
  333. CPaintDC dc(this);
  334. CRect rect;
  335. this->GetClientRect(&rect);
  336. // I will create a bitmap device and render the image into that...
  337. CDC memDC;
  338. memDC.CreateCompatibleDC(&dc);
  339. CBitmap memBitmap;
  340. memBitmap.CreateCompatibleBitmap(&dc, graphicsWidth, graphicsHeight);
  341. CBitmap *pBmp = memDC.SelectObject(&memBitmap);
  342. // I seem to need to clear the bitmap before I draw anything else
  343. // on it. I will do that by drawing an oversized rectangle so that the
  344. // interior of the rectangle covers the entire bitmap.
  345. memDC.SelectStockObject(WHITE_BRUSH);
  346. memDC.SelectStockObject(WHITE_PEN);
  347. memDC.Rectangle(-100, graphicsHeight+100, graphicsWidth+100, -100);
  348. PaintOrPrint(&memDC, NULL, graphicsWidth, graphicsHeight, NULL, NULL);
  349. memDC.SelectStockObject(SYSTEM_FONT);
  350. memDC.SelectObject(pBmp);
  351. // Now I want to form the bitmap into a Device Independent Bitmap (DIB).
  352. // This mainly involves creating a header to stick on the front.
  353. BITMAP bmp;
  354. memBitmap.GetObject(sizeof(BITMAP), &bmp);
  355. WORD cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
  356. if (cClrBits > 24) cClrBits = 32;
  357. else if (cClrBits > 16) cClrBits = 24;
  358. else if (cClrBits > 4) cClrBits = 8;
  359. else if (cClrBits > 1) cClrBits = 4;
  360. else cClrBits = 1;
  361. int psize = (cClrBits >= 24) ? 0 : (1 << cClrBits);
  362. int imageSize = (bmp.bmWidth + 7)/8 * bmp.bmHeight * cClrBits;
  363. int totalSize = sizeof(BITMAPINFOHEADER)+psize*sizeof(RGBQUAD)+imageSize;
  364. HGLOBAL hpbmi = ::GlobalAlloc(GMEM_MOVEABLE, totalSize);
  365. BITMAPINFOHEADER *pbmi = (BITMAPINFOHEADER *)::GlobalLock(hpbmi);
  366. pbmi->biSize = sizeof(BITMAPINFOHEADER);
  367. pbmi->biWidth = bmp.bmWidth;
  368. pbmi->biHeight = bmp.bmHeight;
  369. pbmi->biPlanes = 1;
  370. pbmi->biBitCount = cClrBits;
  371. pbmi->biCompression = BI_RGB; // No compression here
  372. pbmi->biXPelsPerMeter = 0;
  373. pbmi->biYPelsPerMeter = 0;
  374. pbmi->biSizeImage = imageSize;
  375. pbmi->biClrUsed = 0;
  376. pbmi->biClrImportant = 0;
  377. // The bitmap itself needs to be copied out into PBM format, so I have
  378. // to allocate yet another buffer for the information to go into. This may be
  379. // up to another 2.5 Mbytes...
  380. LPBYTE lpBits = (LPBYTE)pbmi + sizeof(BITMAPINFOHEADER) +
  381. psize*sizeof(RGBQUAD);
  382. ::GetDIBits(memDC.m_hDC, (HBITMAP)memBitmap.m_hObject,
  383. 0, (WORD)bmp.bmHeight,
  384. lpBits, (PBITMAPINFO)pbmi, DIB_RGB_COLORS);
  385. ::GlobalUnlock(hpbmi);
  386. *size = totalSize;
  387. *ppsize = psize*sizeof(RGBQUAD);
  388. return hpbmi;
  389. }
  390. void CGraphicsWindow::OnSaveAs()
  391. {
  392. int totalSize;
  393. int psize;
  394. HGLOBAL hpbmi = PaintBitmap(&totalSize, &psize);
  395. void *pbmi = (void *)::GlobalLock(hpbmi);
  396. // With a PMB header created I now get the structure ready to go in a file.
  397. BITMAPFILEHEADER hdr;
  398. hdr.bfType = 0x4d42; // Type = "BM"
  399. hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER)+totalSize);
  400. hdr.bfReserved1 = 0;
  401. hdr.bfReserved2 = 0;
  402. hdr.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) +
  403. sizeof(BITMAPINFOHEADER) +
  404. psize);
  405. CFileDialog fd(FALSE, "dib", "*.dib",
  406. OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
  407. "Bitmaps (*.dib)|*.dib|All Files (*.*)|*.*||", NULL);
  408. if (fd.DoModal() == IDOK)
  409. { FILE *out = fopen(fd.GetPathName(), "wb");
  410. if (out != NULL)
  411. { fwrite((void *)&hdr, sizeof(BITMAPFILEHEADER), 1, out);
  412. fwrite(pbmi, totalSize, 1, out);
  413. fclose(out);
  414. }
  415. }
  416. ::GlobalUnlock(hpbmi);
  417. ::GlobalFree(hpbmi);
  418. }
  419. void CGraphicsWindow::OnPrint()
  420. {
  421. CPrintDialog pd(FALSE);
  422. if (pd.DoModal() != IDOK) return;
  423. CDC PrintDC;
  424. if (PrintDC.CreateDC(pd.GetDriverName(), pd.GetDeviceName(),
  425. pd.GetPortName(), NULL))
  426. { int printWidth = PrintDC.GetDeviceCaps(HORZRES),
  427. printHeight = PrintDC.GetDeviceCaps(VERTRES);
  428. // Also get the size of the print area in mm.
  429. int sizeX = PrintDC.GetDeviceCaps(HORZSIZE),
  430. sizeY = PrintDC.GetDeviceCaps(VERTSIZE);
  431. // I will ensure that the height-to-width ratio of the printed image matches
  432. // that of the screen image. In doing that I am going to ASSUME that screen
  433. // pixels are square, but I will allow for printers that have different
  434. // resolutions in the two directions, eg 600x300 dpi ones. This involves a
  435. // curious mixture of calculations in millimetres and in pixels.
  436. int w = (graphicsHeight*sizeX)/graphicsWidth;
  437. if (w <= sizeY) printHeight = (w*printHeight)/sizeY;
  438. else
  439. { w = (graphicsWidth*sizeY)/graphicsHeight;
  440. printWidth = (w*printWidth)/sizeX;
  441. }
  442. DOCINFO DocInfo;
  443. DocInfo.cbSize = sizeof(DOCINFO);
  444. DocInfo.lpszDocName = "Reduce 3.6 Graphics";
  445. DocInfo.lpszOutput = NULL;
  446. if (PrintDC.StartDoc(&DocInfo) != -1)
  447. {
  448. PrintDC.StartPage();
  449. // This will paint the image in the top left-hand corner of the page. It
  450. // should either be full width across the page or full height down the page,
  451. // depending on the shape on the screen version.
  452. PaintOrPrint(&PrintDC, NULL, printWidth, printHeight, NULL, NULL);
  453. PrintDC.SelectStockObject(BLACK_PEN);
  454. PrintDC.EndPage();
  455. PrintDC.EndDoc();
  456. }
  457. }
  458. GlobalFree(pd.m_pd.hDevMode);
  459. GlobalFree(pd.m_pd.hDevNames);
  460. }
  461. void CGraphicsWindow::OnCopy()
  462. {
  463. int totalSize, psize;
  464. HGLOBAL hpbmi = PaintBitmap(&totalSize, &psize);
  465. if (this->OpenClipboard())
  466. { ::EmptyClipboard();
  467. ::SetClipboardData(CF_DIB, hpbmi);
  468. ::CloseClipboard();
  469. }
  470. }
  471. void CGraphicsWindow::OnClear()
  472. {
  473. DisplayMsg("Graphics Window OnClear");
  474. Invalidate();
  475. }
  476. void CGraphicsWindow::OnRedraw()
  477. {
  478. Invalidate();
  479. }
  480. void CGraphicsWindow::OnViewpoint()
  481. {
  482. viewpointWindow.ShowWindow(viewpointShown ? SW_HIDE : SW_SHOW);
  483. viewpointShown = !viewpointShown;
  484. if (viewpointShown)
  485. { viewpointWindow.Invalidate();
  486. fullyRendered = 1;
  487. }
  488. else if (wirePreview && !fullyRendered) Invalidate();
  489. GetMenu()->CheckMenuItem(IDM_VIEWPOINT,
  490. MF_BYCOMMAND | (viewpointShown ? MF_CHECKED : MF_UNCHECKED));
  491. }
  492. void CGraphicsWindow::OnViewpoint1(UINT a, LONG b)
  493. {
  494. OnViewpoint();
  495. }
  496. void CGraphicsWindow::OnWireframe()
  497. {
  498. drawWire = !drawWire;
  499. GetMenu()->CheckMenuItem(IDM_WIREFRAME,
  500. (drawWire ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
  501. Invalidate();
  502. }
  503. void CGraphicsWindow::OnNoSurface()
  504. {
  505. drawSurface = IDM_NOSURFACE;
  506. GetMenu()->CheckMenuItem(IDM_NOSURFACE, MF_CHECKED | MF_BYCOMMAND);
  507. GetMenu()->CheckMenuItem(IDM_SURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  508. GetMenu()->CheckMenuItem(IDM_SQUARES, MF_UNCHECKED | MF_BYCOMMAND);
  509. GetMenu()->CheckMenuItem(IDM_TRIANGLES, MF_UNCHECKED | MF_BYCOMMAND);
  510. GetMenu()->CheckMenuItem(IDM_SMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  511. GetMenu()->CheckMenuItem(IDM_HISMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  512. if (!drawWire) OnWireframe();
  513. else Invalidate();
  514. }
  515. void CGraphicsWindow::OnSurface()
  516. {
  517. drawSurface = IDM_SURFACE;
  518. GetMenu()->CheckMenuItem(IDM_NOSURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  519. GetMenu()->CheckMenuItem(IDM_SURFACE, MF_CHECKED | MF_BYCOMMAND);
  520. GetMenu()->CheckMenuItem(IDM_SQUARES, MF_UNCHECKED | MF_BYCOMMAND);
  521. GetMenu()->CheckMenuItem(IDM_TRIANGLES, MF_UNCHECKED | MF_BYCOMMAND);
  522. GetMenu()->CheckMenuItem(IDM_SMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  523. GetMenu()->CheckMenuItem(IDM_HISMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  524. if (!drawWire) OnWireframe();
  525. else Invalidate();
  526. }
  527. void CGraphicsWindow::OnSquares()
  528. {
  529. drawSurface = IDM_SQUARES;
  530. GetMenu()->CheckMenuItem(IDM_NOSURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  531. GetMenu()->CheckMenuItem(IDM_SURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  532. GetMenu()->CheckMenuItem(IDM_SQUARES, MF_CHECKED | MF_BYCOMMAND);
  533. GetMenu()->CheckMenuItem(IDM_TRIANGLES, MF_UNCHECKED | MF_BYCOMMAND);
  534. GetMenu()->CheckMenuItem(IDM_SMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  535. GetMenu()->CheckMenuItem(IDM_HISMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  536. Invalidate();
  537. }
  538. void CGraphicsWindow::OnTriangles()
  539. {
  540. drawSurface = IDM_TRIANGLES;
  541. GetMenu()->CheckMenuItem(IDM_NOSURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  542. GetMenu()->CheckMenuItem(IDM_SURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  543. GetMenu()->CheckMenuItem(IDM_SQUARES, MF_UNCHECKED | MF_BYCOMMAND);
  544. GetMenu()->CheckMenuItem(IDM_TRIANGLES, MF_CHECKED | MF_BYCOMMAND);
  545. GetMenu()->CheckMenuItem(IDM_SMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  546. GetMenu()->CheckMenuItem(IDM_HISMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  547. Invalidate();
  548. }
  549. void CGraphicsWindow::OnSmooth()
  550. {
  551. drawSurface = IDM_SMOOTH;
  552. GetMenu()->CheckMenuItem(IDM_NOSURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  553. GetMenu()->CheckMenuItem(IDM_SURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  554. GetMenu()->CheckMenuItem(IDM_SQUARES, MF_UNCHECKED | MF_BYCOMMAND);
  555. GetMenu()->CheckMenuItem(IDM_TRIANGLES, MF_UNCHECKED | MF_BYCOMMAND);
  556. GetMenu()->CheckMenuItem(IDM_SMOOTH, MF_CHECKED | MF_BYCOMMAND);
  557. GetMenu()->CheckMenuItem(IDM_HISMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  558. Invalidate();
  559. }
  560. void CGraphicsWindow::OnHiSmooth()
  561. {
  562. drawSurface = IDM_HISMOOTH;
  563. GetMenu()->CheckMenuItem(IDM_NOSURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  564. GetMenu()->CheckMenuItem(IDM_SURFACE, MF_UNCHECKED | MF_BYCOMMAND);
  565. GetMenu()->CheckMenuItem(IDM_SQUARES, MF_UNCHECKED | MF_BYCOMMAND);
  566. GetMenu()->CheckMenuItem(IDM_TRIANGLES, MF_UNCHECKED | MF_BYCOMMAND);
  567. GetMenu()->CheckMenuItem(IDM_SMOOTH, MF_UNCHECKED | MF_BYCOMMAND);
  568. GetMenu()->CheckMenuItem(IDM_HISMOOTH, MF_CHECKED | MF_BYCOMMAND);
  569. Invalidate();
  570. }
  571. void CGraphicsWindow::OnWirePreview()
  572. {
  573. wirePreview = !wirePreview;
  574. GetMenu()->CheckMenuItem(IDM_WIREPREVIEW,
  575. (wirePreview ? MF_CHECKED : MF_UNCHECKED) | MF_BYCOMMAND);
  576. if (!wirePreview && !fullyRendered) Invalidate();
  577. }
  578. void CGraphicsWindow::OnRotLeft()
  579. {
  580. }
  581. void CGraphicsWindow::OnRotRight()
  582. {
  583. }
  584. void CGraphicsWindow::OnRotUp()
  585. {
  586. }
  587. void CGraphicsWindow::OnRotDown()
  588. {
  589. }
  590. void CGraphicsWindow::OnClockwise()
  591. {
  592. }
  593. void CGraphicsWindow::OnAntiClockwise()
  594. {
  595. }
  596. void CGraphicsWindow::OnEnlarge()
  597. {
  598. }
  599. void CGraphicsWindow::OnShrink()
  600. {
  601. }
  602. #endif
  603. // end of c_graph.cpp