Annotation of OpenXM_contrib2/windows/engine2000/ChildView.cpp, Revision 1.3
1.1 noro 1: // ChildView.cpp : CChildView クラスの動作の定義を行います。
2: //
3:
4: #include "stdafx.h"
5: #include "ox_plot.h"
6: #include "ChildView.h"
7:
8: #ifdef _DEBUG
9: #define new DEBUG_NEW
10: #undef THIS_FILE
11: static char THIS_FILE[] = __FILE__;
12: #endif
13:
14: #include <math.h>
15:
16: extern "C" {
17: #include "ca.h"
18: #include "ifplot.h"
19:
20: #if defined(sun) && !defined(__svr4__)
21: #define EXP10(a) exp10(a)
22: #else
23: #define EXP10(a) pow(10.0,a)
24: #endif
25:
26: HANDLE hResizeNotify,hResizeNotify_Ack;
27: void destroy_canvas(struct canvas *);
28: void pline(int *,struct canvas *, HDC);
29: void draw_wideframe(struct canvas *, HDC);
30: double adjust_scale(double,double);
31: }
32: /////////////////////////////////////////////////////////////////////////////
33: // CChildView
34:
35: CChildView::CChildView()
36: {
37: can = 0;
38: }
39:
40: CChildView::~CChildView()
41: {
42: }
43:
44:
45: BEGIN_MESSAGE_MAP(CChildView,CWnd )
46: //{{AFX_MSG_MAP(CChildView)
47: ON_WM_PAINT()
48: ON_WM_LBUTTONDOWN()
49: ON_WM_MOUSEMOVE()
50: ON_WM_LBUTTONUP()
51: ON_COMMAND(ID_OPT_NOAXIS, OnOptNoaxis)
52: ON_UPDATE_COMMAND_UI(ID_OPT_NOAXIS, OnUpdateOptNoaxis)
53: ON_COMMAND(ID_OPT_PRECISE, OnOptPrecise)
54: ON_UPDATE_COMMAND_UI(ID_OPT_PRECISE, OnUpdateOptPrecise)
55: ON_COMMAND(ID_OPT_WIDE, OnOptWide)
56: ON_UPDATE_COMMAND_UI(ID_OPT_WIDE, OnUpdateOptWide)
57: //}}AFX_MSG_MAP
58: END_MESSAGE_MAP()
59:
60:
61: /////////////////////////////////////////////////////////////////////////////
62: // CChildView メッセージ ハンドラ
63:
64: BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
65: {
66: if (!CWnd::PreCreateWindow(cs))
67: return FALSE;
68:
69: cs.dwExStyle |= WS_EX_CLIENTEDGE;
70: cs.style &= ~WS_BORDER;
71: cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
72: ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
73: return TRUE;
74: }
75:
76: void CChildView::OnPaint()
77: {
78: CPaintDC dc(this); // 描画用のデバイス コンテキスト
79:
80: // TODO: メッセージ ハンドラのコードをここに追加してください。
81:
82: // 描画のために CWnd::OnPaint を呼び出してはいけません。
83: if ( can->mode == MODE_INTERACTIVE ) {
84: ::BitBlt(dc.m_hDC,0,0,can->width,can->height,can->pix,0,0,SRCCOPY);
85: } else {
86: if ( !can->wide ) {
87: ::BitBlt(dc.m_hDC,0,0,can->width,can->height,can->pix,0,0,SRCCOPY);
88: pline(0,can,dc.m_hDC);
89: } else
90: draw_wideframe(can,dc.m_hDC);
91: }
92: BringWindowToTop();
93: }
94:
95: void CChildView::OnPrint(CDC &dc)
96: {
97: DOCINFO docinfo;
98: NODE n;
1.3 ! noro 99: int width,height,ratio,x,y,step;
1.1 noro 100:
101: memset(&docinfo,0,sizeof(DOCINFO));
102: docinfo.cbSize = sizeof(DOCINFO);
103: docinfo.lpszDocName = "test";
104: docinfo.lpszOutput = 0;
105:
106: // black pen
107: CPen pen(PS_SOLID,0,(COLORREF)0);
108: dc.SelectObject(&pen);
109:
110: // black brush
111: CBrush brush((COLORREF)0);
112: dc.SelectObject(&brush);
113:
114: // setup
115: // isotropic mode
116: dc.SetMapMode(MM_ISOTROPIC);
117:
118: // the page size in device pixel
119: width = dc.GetDeviceCaps(HORZRES)*9/10;
120: height = dc.GetDeviceCaps(VERTRES)*9/10;
121:
122: dc.StartDoc(&docinfo);
123: dc.StartPage();
124:
125: if ( can->mode == MODE_INTERACTIVE ) {
1.3 ! noro 126:
! 127: // We want to associate a rectangle of a fixed size to
1.1 noro 128: // one bitmap pixel
129: // if can->width/can->height > width/height
130: // then match the widths, else match the height
131: if ( can->width*height > can->height*width )
132: ratio = width/can->width;
133: else
134: ratio = height/can->height;
135:
136: // set the logical src bitmap size
137: dc.SetWindowExt(can->width*ratio,can->height*ratio);
138:
139: // set the viewport size and the origine in printer pixel
140: dc.SetViewportOrg(width/18,height/18);
141: dc.SetViewportExt(width,height);
142:
1.3 ! noro 143: step = (ratio+4)/5;
1.1 noro 144: for ( n = can->history; n; n = NEXT(n) ) {
145: RealVect *rv = (RealVect *)n->body;
146: if ( rv->len == 2 ) {
147: // dc.SetPixel(rv->body[0],rv->body[1],0);
148: x = rv->body[0]*ratio;
149: y = rv->body[1]*ratio;
150: // dc.FillRect(CRect(x,y,x+1,y+1),&brush);
1.3 ! noro 151: // dc.FillRect(CRect(x-1,y-1,x+1,y+1),&brush);
! 152: dc.FillRect(CRect(x,y,x+step,y+step),&brush);
1.1 noro 153: } else if ( rv->len == 4 ) {
154: dc.MoveTo(rv->body[0]*ratio,rv->body[1]*ratio);
155: dc.LineTo(rv->body[2]*ratio,rv->body[3]*ratio);
156: }
157: }
158: } else {
159: // set the logical src bitmap size
160: dc.SetWindowExt(can->width,can->height);
161:
162: // set the viewport size and the origine in printer pixel
163: dc.SetViewportOrg(width/18,height/18);
164: dc.SetViewportExt(width,height);
165:
166: if ( can->mode == MODE_PLOT )
167: dc.Polyline(can->pa[0].pos,can->pa[0].length);
168: else
169: ::StretchBlt(dc.m_hDC,0,0,can->width,can->height,can->pix,
170: 0,0,can->width,can->height,SRCCOPY);
171: PrintAxis(dc);
172: }
173: dc.EndPage();
174: dc.EndDoc();
175: }
176:
177: void CChildView::PrintAxis(CDC &dc)
178: {
179: #define D 5
180:
1.2 noro 181: double w,w1,e,n;
1.1 noro 182: int x0,y0,x,y,xadj,yadj;
183: char buf[BUFSIZ];
184:
185: /* XXX : should be cleaned up */
186: if ( can->noaxis || (can->mode == MODE_PLOT && !can->pa) )
187: return;
188: if ( can->mode == MODE_INTERACTIVE )
189: return;
190:
191: xadj = yadj = 0;
192: if ( (can->xmin < 0) && (can->xmax > 0) ) {
193: x0 = (int)((can->width)*(-can->xmin/(can->xmax-can->xmin)));
194: dc.MoveTo(x0,0); dc.LineTo(x0,can->height);
195: } else if ( can->xmin >= 0 )
196: x0 = 0;
197: else
198: x0 = can->width-D;
199: if ( (can->ymin < 0) && (can->ymax > 0) ) {
200: y0 = (int)((can->height)*(can->ymax/(can->ymax-can->ymin)));
201: dc.MoveTo(0,y0); dc.LineTo(can->width,y0);
202: } else if ( can->ymin >= 0 )
203: y0 = can->height;
204: else
205: y0 = D;
206: w = can->xmax-can->xmin;
207: w1 = w * DEFAULTWIDTH/can->width;
208: e = adjust_scale(EXP10(floor(log10(w1))),w1);
209: for ( n = ceil(can->xmin/e); n*e<= can->xmax; n++ ) {
1.2 noro 210: x = (int)(can->width*(n*e-can->xmin)/w);
1.1 noro 211: dc.MoveTo(x,y0); dc.LineTo(x,y0-D);
212: sprintf(buf,"%g",n*e);
213: dc.TextOut(x+2,y0+2,buf,strlen(buf));
214: }
215: w = can->ymax-can->ymin;
216: w1 = w * DEFAULTHEIGHT/can->height;
217: e = adjust_scale(EXP10(floor(log10(w1))),w1);
218: for ( n = ceil(can->ymin/e); n*e<= can->ymax; n++ ) {
1.2 noro 219: y = (int)(can->height*(1-(n*e-can->ymin)/w));
1.1 noro 220: dc.MoveTo(x0,y); dc.LineTo(x0+D,y);
221: sprintf(buf,"%g",n*e);
222: if ( can->xmax <= 0 ) {
223: xadj = dc.GetOutputTextExtent(buf,strlen(buf)).cx;
224: }
225: dc.TextOut(x0+2-xadj,y+2,buf,strlen(buf));
226: }
227: }
228:
229: static CPoint start,prev;
230:
231: void CChildView::OnLButtonDown(UINT nFlags, CPoint point) {
232: start = point;
233: prev = point;
234: SetCapture();
235: CWnd::OnLButtonDown(nFlags,point);
236: }
237:
238: void CChildView::OnMouseMove(UINT nFlags, CPoint point) {
239: if ( nFlags & MK_LBUTTON ) {
240: CDC *pDC = GetDC();
241: CRect prevrect(start,prev),rect(start,point);
242: CSize size(1,1);
243:
244: pDC->DrawDragRect(&rect,size,&prevrect,size);
245: ReleaseDC(pDC);
246: prev = point;
247: }
248: CWnd::OnMouseMove(nFlags,point);
249: }
250:
251: void CChildView::OnLButtonUp(UINT nFlags, CPoint point) {
252: CDC *pDC = GetDC();
253: CRect rect(start,point);
254: CSize size(1,1);
255:
256: pDC->DrawDragRect(&rect,size,0,size);
257: ReleaseDC(pDC);
258: ReleaseCapture();
259: start_point = start; end_point = point;
260: current_can = can;
261: SetEvent(hResizeNotify);
262: WaitForSingleObject(hResizeNotify_Ack,(DWORD)-1);
263:
264: CWnd::OnLButtonUp(nFlags,point);
265: }
266:
267: void CChildView::DestroyCanvas() {
268: destroy_canvas(can);
269: }
270:
271: void CChildView::OnOptNoaxis()
272: {
273: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
274: can->noaxis = !can->noaxis;
275: RedrawWindow();
276: }
277:
278: void CChildView::OnUpdateOptNoaxis(CCmdUI* pCmdUI)
279: {
280: // TODO: この位置に command update UI ハンドラ用のコードを追加してください
281: pCmdUI->SetCheck(can->noaxis);
282: }
283:
284: void CChildView::OnOptPrecise()
285: {
286: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
287: can->precise = !can->precise;
288: }
289:
290: void CChildView::OnUpdateOptPrecise(CCmdUI* pCmdUI)
291: {
292: // TODO: この位置に command update UI ハンドラ用のコードを追加してください
293: pCmdUI->SetCheck(can->precise);
294: }
295:
296: void CChildView::OnOptWide()
297: {
298: // TODO: この位置にコマンド ハンドラ用のコードを追加してください
299: can->wide = !can->wide;
300: RedrawWindow();
301: }
302:
303: void CChildView::OnUpdateOptWide(CCmdUI* pCmdUI)
304: {
305: // TODO: この位置に command update UI ハンドラ用のコードを追加してください
306: pCmdUI->SetCheck(can->wide);
307: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>