// ChildView.cpp : CChildView クラスの動作の定義を行います。 // #include "stdafx.h" #include "ox_plot.h" #include "ChildView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #include extern "C" { #include "if_canvas.h" struct pa { int length; POINT *pos; }; typedef struct RealVect { int len; int body[1]; } RealVect; #define EXP10(a) pow(10.0,a) extern struct canvas *current_can; extern POINT start_point,end_point; HANDLE hResizeNotify,hResizeNotify_Ack; void destroy_canvas(struct canvas *); void pline(int *,struct canvas *, HDC); void draw_wideframe(struct canvas *, HDC); double adjust_scale(double,double); } ///////////////////////////////////////////////////////////////////////////// // CChildView CChildView::CChildView() { can = 0; } CChildView::~CChildView() { } BEGIN_MESSAGE_MAP(CChildView,CWnd ) //{{AFX_MSG_MAP(CChildView) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_COMMAND(ID_OPT_NOAXIS, OnOptNoaxis) ON_UPDATE_COMMAND_UI(ID_OPT_NOAXIS, OnUpdateOptNoaxis) ON_COMMAND(ID_OPT_PRECISE, OnOptPrecise) ON_UPDATE_COMMAND_UI(ID_OPT_PRECISE, OnUpdateOptPrecise) ON_COMMAND(ID_OPT_WIDE, OnOptWide) ON_UPDATE_COMMAND_UI(ID_OPT_WIDE, OnUpdateOptWide) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChildView メッセージ ハンドラ BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) { if (!CWnd::PreCreateWindow(cs)) return FALSE; cs.dwExStyle |= WS_EX_CLIENTEDGE; cs.style &= ~WS_BORDER; cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); return TRUE; } void CChildView::OnPaint() { CPaintDC dc(this); // 描画用のデバイス コンテキスト // TODO: メッセージ ハンドラのコードをここに追加してください。 // 描画のために CWnd::OnPaint を呼び出してはいけません。 if ( canvas_is_interactive(can) ) { canvas_bitblt(can,dc.m_hDC,0,0); } else { if ( !canvas_wide(can) ) { canvas_bitblt(can,dc.m_hDC,0,0); pline(0,can,dc.m_hDC); } else draw_wideframe(can,dc.m_hDC); } BringWindowToTop(); } void CChildView::OnPrint(CDC &dc) { DOCINFO docinfo; // NODE n; int width,height,ratio,x,y,step; int ch,cw,len,i; memset(&docinfo,0,sizeof(DOCINFO)); docinfo.cbSize = sizeof(DOCINFO); docinfo.lpszDocName = "test"; docinfo.lpszOutput = 0; // black pen CPen pen(PS_SOLID,0,(COLORREF)0); dc.SelectObject(&pen); // black brush CBrush brush((COLORREF)0); dc.SelectObject(&brush); // setup // isotropic mode dc.SetMapMode(MM_ISOTROPIC); // the page size in device pixel width = dc.GetDeviceCaps(HORZRES)*9/10; height = dc.GetDeviceCaps(VERTRES)*9/10; dc.StartDoc(&docinfo); dc.StartPage(); cw = canvas_width(can); ch = canvas_height(can); if ( canvas_is_interactive(can) ) { // We want to associate a rectangle of a fixed size to // one bitmap pixel // if cw/ch > width/height // then match the widths, else match the height if ( cw*height > ch*width ) ratio = width/cw; else ratio = height/ch; // set the logical src bitmap size dc.SetWindowExt(cw*ratio,ch*ratio); // set the viewport size and the origine in printer pixel dc.SetViewportOrg(width/18,height/18); dc.SetViewportExt(width,height); step = (ratio+4)/5; RealVect **p = (RealVect **)canvas_history(can, &len); for(i=0; ilen == 2 ) { // dc.SetPixel(rv->body[0],rv->body[1],0); x = rv->body[0]*ratio; y = rv->body[1]*ratio; // dc.FillRect(CRect(x,y,x+1,y+1),&brush); // dc.FillRect(CRect(x-1,y-1,x+1,y+1),&brush); dc.FillRect(CRect(x,y,x+step,y+step),&brush); } else if ( rv->len == 4 ) { dc.MoveTo(rv->body[0]*ratio,rv->body[1]*ratio); dc.LineTo(rv->body[2]*ratio,rv->body[3]*ratio); } } } else { // set the logical src bitmap size dc.SetWindowExt(cw,ch); // set the viewport size and the origine in printer pixel dc.SetViewportOrg(width/18,height/18); dc.SetViewportExt(width,height); if ( canvas_is_plot(can) ) dc.Polyline(canvas_pa(can)->pos,canvas_pa(can)->length); else ::StretchBlt(dc.m_hDC,0,0,cw,ch,canvas_pix(can),0,0,cw,ch,SRCCOPY); PrintAxis(dc); } dc.EndPage(); dc.EndDoc(); } void CChildView::PrintAxis(CDC &dc) { #define D 5 #define DEFAULTWIDTH 400 #define DEFAULTHEIGHT 400 double w,w1,e,n; int x0,y0,x,y,xadj,yadj; char buf[BUFSIZ]; double cxmin,cxmax,cymin,cymax; int cw,ch; cxmin = canvas_xmin(can); cxmax = canvas_xmax(can); cymin = canvas_ymin(can); cymax = canvas_ymax(can); cw = canvas_width(can); ch = canvas_height(can); /* XXX : should be cleaned up */ if ( canvas_noaxis(can) || (canvas_is_plot(can) && !canvas_pa(can)) || canvas_is_interactive(can) ) return; xadj = yadj = 0; if ( (cxmin < 0) && (cxmax > 0) ) { x0 = (int)((cw)*(-cxmin/(cxmax-cxmin))); dc.MoveTo(x0,0); dc.LineTo(x0,ch); } else if ( cxmin >= 0 ) x0 = 0; else x0 = cw-D; if ( (cymin < 0) && (cymax > 0) ) { y0 = (int)((ch)*(cymax/(cymax-cymin))); dc.MoveTo(0,y0); dc.LineTo(cw,y0); } else if ( cymin >= 0 ) y0 = ch; else y0 = D; w = cxmax-cxmin; w1 = w * DEFAULTWIDTH/cw; e = adjust_scale(EXP10(floor(log10(w1))),w1); for ( n = ceil(cxmin/e); n*e<= cxmax; n++ ) { x = (int)(cw*(n*e-cxmin)/w); dc.MoveTo(x,y0); dc.LineTo(x,y0-D); sprintf(buf,"%g",n*e); dc.TextOut(x+2,y0+2,buf,strlen(buf)); } w = cymax-cymin; w1 = w * DEFAULTHEIGHT/ch; e = adjust_scale(EXP10(floor(log10(w1))),w1); for ( n = ceil(cymin/e); n*e<= cymax; n++ ) { y = (int)(ch*(1-(n*e-cymin)/w)); dc.MoveTo(x0,y); dc.LineTo(x0+D,y); sprintf(buf,"%g",n*e); if ( cxmax <= 0 ) { xadj = dc.GetOutputTextExtent(buf,strlen(buf)).cx; } dc.TextOut(x0+2-xadj,y+2,buf,strlen(buf)); } } static CPoint start,prev; void CChildView::OnLButtonDown(UINT nFlags, CPoint point) { start = point; prev = point; SetCapture(); CWnd::OnLButtonDown(nFlags,point); } void CChildView::OnMouseMove(UINT nFlags, CPoint point) { if ( nFlags & MK_LBUTTON ) { CDC *pDC = GetDC(); CRect prevrect(start,prev),rect(start,point); CSize size(1,1); pDC->DrawDragRect(&rect,size,&prevrect,size); ReleaseDC(pDC); prev = point; } CWnd::OnMouseMove(nFlags,point); } void CChildView::OnLButtonUp(UINT nFlags, CPoint point) { CDC *pDC = GetDC(); CRect rect(start,point); CSize size(1,1); pDC->DrawDragRect(&rect,size,0,size); ReleaseDC(pDC); ReleaseCapture(); start_point = start; end_point = point; current_can = can; SetEvent(hResizeNotify); WaitForSingleObject(hResizeNotify_Ack,(DWORD)-1); CWnd::OnLButtonUp(nFlags,point); } void CChildView::DestroyCanvas() { destroy_canvas(can); } void CChildView::OnOptNoaxis() { // TODO: この位置にコマンド ハンドラ用のコードを追加してください canvas_toggle_noaxis(can); RedrawWindow(); } void CChildView::OnUpdateOptNoaxis(CCmdUI* pCmdUI) { // TODO: この位置に command update UI ハンドラ用のコードを追加してください pCmdUI->SetCheck(canvas_noaxis(can)); } void CChildView::OnOptPrecise() { // TODO: この位置にコマンド ハンドラ用のコードを追加してください canvas_toggle_precise(can); } void CChildView::OnUpdateOptPrecise(CCmdUI* pCmdUI) { // TODO: この位置に command update UI ハンドラ用のコードを追加してください pCmdUI->SetCheck(canvas_precise(can)); } void CChildView::OnOptWide() { // TODO: この位置にコマンド ハンドラ用のコードを追加してください canvas_toggle_wide(can); RedrawWindow(); } void CChildView::OnUpdateOptWide(CCmdUI* pCmdUI) { // TODO: この位置に command update UI ハンドラ用のコードを追加してください pCmdUI->SetCheck(canvas_wide(can)); }