c_graph.cpp 21 KB

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