Mil学习之显示、鼠标交互、交互绘图、交互Mask

        将常用的Mil绘图功能集成到了一起,里面分成两个类:一个用来显示、一个用来交互绘制。绘制部分几乎集成了所有常用功能,包括矩形、旋转矩形、圆形、圆弧、圆形ROI、弧形ROI、椭圆形、半透Mask掩膜。

附代码 (Mil X)  - 绘制部分

// MilDrtaw
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Matrox.MatroxImagingLibrary;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace MilDraw
{
    public struct MilPoint
    {
        public double x;
        public double y;
        public void CopyTo(ref MilPoint Pt)
        {
            Pt.x = x; Pt.y = y;
        }
    }
    public struct MilSegment
    {
        public MilPoint ptS;
        public MilPoint ptE;
    }
    public struct MilLine
    {
        public double A;
        public double B;
        public double C;

        public double Get_k()
        {
            double dk = 0;
            if (B != 0)
                dk = (-1) * A / B;
            else
                dk = (-1) * A > 0 ? 0 / .0 : 0 / .0;
            return dk;
        }

        public double Get_b()
        {
            double db = 0;
            if (B != 0)
                db = (-1) * C / B;
            else
                db = (-1) * C > 0 ? 0 / .0 : 0 / .0;
            return db;
        }
    }
    public struct Rect
    {
        public MilPoint ptTL;
        public MilPoint ptDR;
    }
    public struct RectAngle
    {
        public MilPoint ptCenter;
        public double Width;
        public double Height;
        public double Angle;
    }
    public struct Arc
    {
        public MilPoint ptCenter;
        public double AngleS;
        public double AngleE;
        public double dRx;
        public double dRy;
    }
    public struct ArcRegion
    {
        public MilPoint ptCenter;
        public double AngleS;
        public double AngleE;
        public double dR;
        public double dRmin;
        public double dRmax;
    }
    public struct Circle
    {
        public MilPoint ptCenter;
        public double dRx;
        public double dRy;
        public double Angle;
    }
    public struct CircleRegion
    {
        public MilPoint ptCenter;
        public double dR;
        public double dRmin;
        public double dRmax;
    }
    public enum DRAW_TYPE
    {
        DRAW_NONE,
        DRAW_LINE,
        DRAW_RECT,
        DRAW_RECT_ANGLE,
        DRAW_CIRCLE,
        DRAW_CIRCLE_REGION,
        DRAW_ARC,
        DRAW_ARC_REGION,
        DRAW_ELLIPSE,
        //DRAW_ELLIPSE_ARC,// Mil这个绘图有Bug,会晃动
        DRAW_POLYLINE,
        DRAW_POLYGON,
        DRAW_MASK
    }


    public class MilGraphicShow
    {
        public MIL_ID MilSystem;
        public MIL_ID MilDisplay;
        public MIL_ID MilGraphList;
        public MIL_ID MilGraphContext;
        public MIL_ID MilImage;
        public int MilImageSizeX;
        public int MilImageSizeY;
        public bool MouseLeftKeyDown;
        public bool MouseRightKeyDown;
        public GCHandle thisPtr;
        public Panel panel = null;
        public MilGraphicDraw draw = null;

        public MilPoint ptRoiInImageStart;   // ROI移动时调用,起点
        public MilPoint ptRoiInImageEnd;     // ROI移动时调用,终点
        public MilPoint ptCurMousePos;       // 当前鼠标在Panel控件的像素坐标
        public MilPoint ptCurPixelPos;       // 当前鼠标缩放到原图中的实时像素坐标
        public MilPoint ptPixelBtnLDown;     // 当前鼠标左键点下放到原图像素坐标
        public MilPoint ptPixelBtnLUp;       // 当前鼠标左键抬起放到原图像素坐标

        // 托管函数句柄
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseMoveHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseMoveHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseLeftKeyDownHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseLeftKeyDownHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseLeftKeyUpHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseLeftKeyUpHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseRightKeyDownHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseRightKeyDownHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseRightKeyUpHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseRightKeyUpHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR ROIChangeEndHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(ROIChangeEndHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR ROIChangeHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(ROIChangeHookFunc);
        public static MIL_GRA_HOOK_FUNCTION_PTR GraHookFuncPtr = new MIL_GRA_HOOK_FUNCTION_PTR(GraHookFunc);

        public MilGraphicShow(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDispImage, Panel panel_)
        {
            MilGraphList = MIL.M_NULL;
            MilGraphContext = MIL.M_NULL;
            MilImage = MIL.M_NULL;
            thisPtr = GCHandle.Alloc(this);

            if (MilDisplay != MIL.M_NULL && MilSystem != MIL.M_NULL)
            {
                this.MilSystem = MilSystem;
                this.MilDisplay = MilDisplay;
                this.MilImage = MilDispImage;
                this.panel = panel_;
                MilImageSizeX = (int)MIL.MbufInquire(MilImage, MIL.M_SIZE_X, MIL.M_NULL);
                MilImageSizeY = (int)MIL.MbufInquire(MilImage, MIL.M_SIZE_Y, MIL.M_NULL);

                if (panel_.Handle != IntPtr.Zero && MilDispImage != MIL.M_NULL)
                {
                    MIL.MgraAlloc(MilSystem, ref MilGraphContext);
                    MIL.MdispSelectWindow(MilDisplay, MilDispImage, panel_.Handle);
                    MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref MilGraphList);
                    MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphList);
                }
                MIL.MdispControl(MilDisplay, MIL.M_CENTER_DISPLAY, MIL.M_ENABLE);
                MIL.MdispControl(MilDisplay, MIL.M_SCALE_DISPLAY, MIL.M_ENABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_USE, MIL.M_ENABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_CURSOR_CHANGE, MIL.M_ENABLE);

                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_MOVE, MouseMoveHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_DOWN, MouseLeftKeyDownHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_UP, MouseLeftKeyUpHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_RIGHT_BUTTON_DOWN, MouseRightKeyDownHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_RIGHT_BUTTON_UP, MouseRightKeyUpHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE_END, ROIChangeEndHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE, ROIChangeHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MgraHookFunction(MilGraphList, MIL.M_GRAPHIC_MODIFIED, GraHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

            }
        }
        public void MilFree()
        {
            if (MilDisplay != MIL.M_NULL)
            {
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_MOVE + MIL.M_UNHOOK, MouseMoveHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_DOWN + MIL.M_UNHOOK, MouseLeftKeyDownHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_UP + MIL.M_UNHOOK, MouseLeftKeyUpHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE_END + MIL.M_UNHOOK, ROIChangeEndHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE + MIL.M_UNHOOK, ROIChangeHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

                MIL.MgraHookFunction(MilGraphList, MIL.M_GRAPHIC_MODIFIED + MIL.M_UNHOOK, GraHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

                MIL.MdispControl(MilDisplay, MIL.M_CENTER_DISPLAY, MIL.M_DISABLE);
                MIL.MdispControl(MilDisplay, MIL.M_SCALE_DISPLAY, MIL.M_DISABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_USE, MIL.M_DISABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_CURSOR_CHANGE, MIL.M_DISABLE);
            }

            if (MilGraphList != MIL.M_NULL)
            {
                MIL.MgraFree(MilGraphList);
                MilGraphList = MIL.M_NULL;
            }

            if (MilGraphContext != MIL.M_NULL)
            {
                MIL.MgraFree(MilGraphContext);
                MilGraphContext = MIL.M_NULL;
            }

        }

        static MIL_INT MouseMoveHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_INT px = 0;
            MIL_INT py = 0;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_X, ref px); graphic.ptCurMousePos.x = px;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_Y, ref py); graphic.ptCurMousePos.y = py;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptCurPixelPos.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptCurPixelPos.y);
            if (graphic.draw != null)
                graphic.draw.MouseMove(EventID);

            return 0;
        }
        static MIL_INT MouseLeftKeyDownHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            graphic.MouseLeftKeyDown = true;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLDown.y);
            if (graphic.draw != null)
                graphic.draw.BtnLDown(EventID);
            return 0;
        }
        static MIL_INT MouseLeftKeyUpHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLUp.y);
            if (graphic.draw != null)
                graphic.draw.BtnLUp(EventID);
            graphic.MouseLeftKeyDown = false;

            return 0;
        }
        static MIL_INT MouseRightKeyDownHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            graphic.MouseRightKeyDown = true;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLDown.y);
            if (graphic.draw != null)
                graphic.draw.BtnRDown(EventID);
            return 0;
        }
        static MIL_INT MouseRightKeyUpHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLUp.y);
            if (graphic.draw != null)
                graphic.draw.BtnRUp(EventID);
            graphic.MouseRightKeyDown = false;

            return 0;
        }
        static MIL_INT ROIChangeEndHookFunc(MIL_INT HookType, MIL_ID MilEvent, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_ID DisplayID = graphic.MilDisplay;
            graphic.ptRoiInImageStart.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_X, MIL.M_NULL);
            graphic.ptRoiInImageStart.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_Y, MIL.M_NULL);
            graphic.ptRoiInImageEnd.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_X, MIL.M_NULL) + graphic.ptRoiInImageStart.x;
            graphic.ptRoiInImageEnd.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_Y, MIL.M_NULL) + graphic.ptRoiInImageStart.y;

            if (graphic.draw != null)
            {
                graphic.ptRoiInImageStart.CopyTo(ref graphic.draw.rect.ptTL);
                graphic.ptRoiInImageEnd.CopyTo(ref graphic.draw.rect.ptDR);
            }
            return 0;
        }
        static MIL_INT ROIChangeHookFunc(MIL_INT HookType, MIL_ID MilEvent, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_ID DisplayID = graphic.MilDisplay;
            graphic.ptRoiInImageStart.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_X, MIL.M_NULL);
            graphic.ptRoiInImageStart.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_Y, MIL.M_NULL);
            graphic.ptRoiInImageEnd.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_X, MIL.M_NULL) + graphic.ptRoiInImageStart.x;
            graphic.ptRoiInImageEnd.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_Y, MIL.M_NULL) + graphic.ptRoiInImageStart.y;

            if (graphic.draw != null)
            {
                graphic.ptRoiInImageStart.CopyTo(ref graphic.draw.rect.ptTL);
                graphic.ptRoiInImageEnd.CopyTo(ref graphic.draw.rect.ptDR);
            }

            return 0;
        }
        static MIL_INT GraHookFunc(MIL_INT HookType, MIL_ID EventId, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_INT nLabel = 0;
            MIL_INT nType = 0;
            MIL_ID MilGraphList = graphic.MilGraphList;

            MIL.MgraInquireList(graphic.MilGraphList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref nLabel);
            if (nLabel <= 0 || nLabel >= 100) return 0;

            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_GRAPHIC_TYPE, ref nType);
            if (graphic.draw != null)
                graphic.draw.CallBackiInquire(MilGraphList, nLabel);

            return 0;
        }

        public void DispZoom(double ZoomFactorToApplyX, double ZoomFactorToApplyY)
        {
            MIL.MdispZoom(MilDisplay, ZoomFactorToApplyX, ZoomFactorToApplyY);
        }
        public void DispZoomOut()
        {
            if (MilDisplay != MIL.M_NULL)
            {
                double ZoomX = 1, ZoomY = 1;
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_X, ref ZoomX);
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_Y, ref ZoomY);

                if ((ZoomX >= 0.125) && (ZoomY >= 0.125))
                {
                    ZoomX /= 1.5;
                    ZoomY /= 1.5;
                }
                DispZoom(ZoomX, ZoomY);
            }
        }
        public void DispZoomIn()
        {
            if (MilDisplay != MIL.M_NULL)
            {
                double ZoomX = 1, ZoomY = 1;
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_X, ref ZoomX);
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_Y, ref ZoomY);

                if ((ZoomX <= 8) && (ZoomY <= 8))
                {
                    ZoomX *= 1.5;
                    ZoomY *= 1.5;
                }
                DispZoom(ZoomX, ZoomY);
            }
        }
        public void DispFit()
        {
            double dX = panel.Width * 1.0 / MIL.MbufInquire(MilImage, MIL.M_SIZE_X, MIL.M_NULL);
            double dY = panel.Height * 1.0 / MIL.MbufInquire(MilImage, MIL.M_SIZE_Y, MIL.M_NULL);
            double dF = dX < dY ? dX : dY;
            DispZoom(dF, dF);
        }
        public void DispMouseUse(bool bEnable)
        {
            MIL.MdispControl(MilDisplay, MIL.M_MOUSE_USE, bEnable ? MIL.M_ENABLE : MIL.M_DISABLE);
        }
    }


    public class MilGraphicDraw : Math__
    {
        MilGraphicShow show = null;
        public DRAW_TYPE drawType = DRAW_TYPE.DRAW_NONE;

        int nCircleCenterSize = 5;
        int nPtIndex = -2;
        bool bOnDraw = false;
        bool bExitThr = false;

        public int nMaskHalfPenSize = 10;
        public int nMaskAlpha = 100;  // 混合浓度
        MIL_ID MilOverlay = 0;   // Mil的绘图图层
        MIL_ID MilImageMask = 0; // 实际绘制的图片(Mask)
        MIL_INT MilBackColor = 0;  // 背景色
        MIL_INT MilForeColor = 0;  // 前景色
        MIL_INT MilTransparentColor = 0;  // Mil计算出的透明颜色存放 ID

        MilPoint PtNow = new MilPoint();
        MilPoint PtNowLast = new MilPoint();
        MilPoint ptPixelBtnLDown = new MilPoint();
        MilPoint ptPixelBtnLUp = new MilPoint();
        MilPoint[] MilPts = new MilPoint[20];
        Stopwatch DrawInterval = Stopwatch.StartNew();

        public MilSegment segment = new MilSegment();
        public MilPoint[] polyLine = new MilPoint[10];
        public Rect rect = new Rect();
        public RectAngle rectAngle;
        public Arc arc = new Arc();
        public ArcRegion arcRegion = new ArcRegion();
        public Circle circle = new Circle();
        public CircleRegion circleRegion = new CircleRegion();
        public Arc ellipseArc = new Arc();
        public Circle ellipse = new Circle();

        public MilGraphicDraw(MilGraphicShow show_)
        {
            show = show_;
            show.draw = this;

            InitMask();
            Thread thr = new Thread(thrDraw);
            thr.IsBackground = true;
            thr.Start();
        }
        public void MilFree()
        {
            show.draw = null;
            bExitThr = true;

            if (MilImageMask != 0)
                MIL.MbufFree(MilImageMask);
        }

        public void SetDrawType(DRAW_TYPE type)
        {
            if (bOnDraw == false)
                drawType = type;
        }
        public void SetDrawColor(double MilColor)
        {
            MIL.MgraColor(show.MilGraphContext, MilColor);
        }

        public void MouseMove(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref PtNow.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref PtNow.y);

            DrawMask(EventID);
        }
        public void BtnLDown(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLDown.y);

            if (drawType == DRAW_TYPE.DRAW_RECT)
                nPtIndex = 0;
            DrawMask(EventID);
        }
        public void BtnLUp(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLUp.y);

            if (nPtIndex >= 0 && nPtIndex <= 9 && GetPointToPointDist(ptPixelBtnLUp, MilPts[nPtIndex]) >= 5)
            { nPtIndex++; ptPixelBtnLUp.CopyTo(ref MilPts[nPtIndex]); }
            if (nPtIndex == -2)
                nPtIndex++;
            if (nPtIndex == -1 && ptPixelBtnLUp.x * ptPixelBtnLUp.y > 0)
            { ptPixelBtnLUp.CopyTo(ref MilPts[0]); nPtIndex++; }
            if (drawType == DRAW_TYPE.DRAW_RECT && nPtIndex < -10)
                nPtIndex = 1;
        }
        public void BtnRDown(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLDown.y);

            DrawMask(EventID);
        }
        public void BtnRUp(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLUp.y);


        }
        public void DrawStart()
        {
            if(drawType != DRAW_TYPE.DRAW_MASK)
                ClearGraphic();
            bOnDraw = true;
            nPtIndex = -2;
        }
        public void DrawEnd()
        {
            bOnDraw = false;
            MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_DISABLE);
            MIL.MdispControl(show.MilDisplay, MIL.M_ROI_DEFINE, MIL.M_STOP);
            MIL.MdispControl(show.MilDisplay, MIL.M_ROI_SHOW, MIL.M_DISABLE);
            MIL.MdispControl(show.MilDisplay, MIL.M_ROI_RESET, MIL.M_DEFAULT);

            DrawOnEnd();
        }

        void thrDraw()
        {
            while (bExitThr == false)
            {
                Thread.Sleep(10);
                if (bOnDraw == false) continue;
                if (DrawInterval.ElapsedMilliseconds <= 50) continue;
                if (nPtIndex < 0 || nPtIndex > 9) continue;
                if (GetPointToPointDist(PtNow, ptPixelBtnLUp) <= 1) continue;
                if (GetPointToPointDist(PtNow, PtNowLast) <= 1) continue;
                if (drawType == DRAW_TYPE.DRAW_NONE) continue;

                DrawInterval.Restart();
                PtNow.CopyTo(ref PtNowLast);

                MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_DISABLE);
                if (drawType == DRAW_TYPE.DRAW_ARC)
                    DrawArc();
                if (drawType == DRAW_TYPE.DRAW_ARC_REGION)
                    DrawArcRegion();
                if (drawType == DRAW_TYPE.DRAW_CIRCLE)
                    DrawCircle();
                if (drawType == DRAW_TYPE.DRAW_CIRCLE_REGION)
                    DrawCircleRegion();
                if (drawType == DRAW_TYPE.DRAW_RECT)
                    DrawRect();
                if (drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
                    DrawRectAngle();
                if (drawType == DRAW_TYPE.DRAW_LINE)
                    DrawLine();
                if (drawType == DRAW_TYPE.DRAW_POLYLINE)
                    DrawPolyline();
                if (drawType == DRAW_TYPE.DRAW_POLYGON)
                    DrawPolygon();
                if (drawType == DRAW_TYPE.DRAW_ELLIPSE)
                    DrawEllipse();
                //if (drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
                //    DrawEllipseArc();
                MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_ENABLE);
            }
        }
        void DrawArc()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_SQUARE_ASPECT_RATIO, MIL.M_ARC_THREE_POINTS);
            }
        }
        void DrawArcRegion()
        {
            ClearGraphic();

            if (nPtIndex == 0)
            {
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawLine(MilPts[0], PtNow);
                arcRegion.AngleS = 0;
            }
            if (nPtIndex == 1)
            {
                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                MilPoint PtTmp = new MilPoint();
                MilLine line = new MilLine();
                GetLine(MilPts[0], MilPts[1], ref line);
                bool bStartPt = false;

                if (line.A != 0)
                {
                    double dX = (line.B * PtNow.y + line.C) / line.A * (-1);
                    bStartPt = dX > PtNow.x;//true=上点是起点  false=下点是起点

                    // 确定弧绘制起点和终点
                    if (bStartPt == (MilPts[0].y > MilPts[1].y))
                    {
                        MilPts[1].CopyTo(ref PtS);
                        MilPts[0].CopyTo(ref PtE);
                    }
                    else
                    {
                        MilPts[0].CopyTo(ref PtS);
                        MilPts[1].CopyTo(ref PtE);
                    }
                }
                else
                {
                    MilPts[1].y += 0.1;
                    return;
                }
                GetCircleCenter(MilPts[0], MilPts[1], PtNow, ref MilPts[4]);
                MilPts[4].CopyTo(ref PtTmp); PtTmp.x = 10000;

                // 计算角度
                arcRegion.AngleS = R2D(GetAngle(PtS, MilPts[4], PtTmp));
                arcRegion.AngleE = R2D(GetAngle(PtE, MilPts[4], PtTmp));
                if (PtS.y > MilPts[4].y) arcRegion.AngleS = 360 - arcRegion.AngleS;
                if (PtE.y > MilPts[4].y) arcRegion.AngleE = 360 - arcRegion.AngleE;

                double dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCircle(MilPts[4], nCircleCenterSize, nCircleCenterSize);
                DrawArc(MilPts[4], dR, dR, arcRegion.AngleS, arcRegion.AngleE);
            }
            if (nPtIndex == 2)
            {
                MilPts[4].CopyTo(ref arcRegion.ptCenter);
                arcRegion.dR = GetPointToPointDist(arcRegion.ptCenter, MilPts[0]);
                double dDist_ = Math.Abs(GetPointToPointDist(arcRegion.ptCenter, PtNow) - arcRegion.dR);
                arcRegion.dRmin = arcRegion.dR - dDist_;
                arcRegion.dRmax = arcRegion.dR + dDist_;
                if (arcRegion.dRmin <= 0) arcRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawArc(arcRegion.ptCenter, arcRegion.dR, arcRegion.dR, arcRegion.AngleS, arcRegion.AngleE);
                DrawCircle(arcRegion.ptCenter, nCircleCenterSize, nCircleCenterSize);

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmin, arcRegion.dRmin, arcRegion.AngleS, arcRegion.AngleE);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmax, arcRegion.dRmax, arcRegion.AngleS, arcRegion.AngleE);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);
            }
            if (nPtIndex == 3)
            {
                double dDist_ = Math.Abs(GetPointToPointDist(arcRegion.ptCenter, MilPts[3]) - arcRegion.dR);
                arcRegion.dRmin = arcRegion.dR - dDist_;
                arcRegion.dRmax = arcRegion.dR + dDist_;
                if (arcRegion.dRmin <= 0) arcRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawArc(arcRegion.ptCenter, arcRegion.dR, arcRegion.dR, arcRegion.AngleS, arcRegion.AngleE);
                SetDrawColor(MIL.M_COLOR_GREEN);

                DrawCircle(arcRegion.ptCenter, nCircleCenterSize, nCircleCenterSize);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmin, arcRegion.dRmin, arcRegion.AngleS, arcRegion.AngleE);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmax, arcRegion.dRmax, arcRegion.AngleS, arcRegion.AngleE);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                nPtIndex = -2;
            }
        }
        void DrawCircle()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);// M_ROTATABLE 
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_SQUARE_ASPECT_RATIO, MIL.M_CIRCLE);
            }
        }
        void DrawCircleRegion()
        {
            ClearGraphic();

            if (nPtIndex == 0)
            {
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawLine(MilPts[0], PtNow);
            }
            if (nPtIndex == 1)
            {
                GetCircleCenter(MilPts[0], MilPts[1], PtNow, ref MilPts[4]);
                double dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCircle(MilPts[4], 5, 5);
                DrawCircle(MilPts[4], dR, dR);
            }
            if (nPtIndex == 2)
            {
                MilPts[4].CopyTo(ref circleRegion.ptCenter);
                circleRegion.dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                double dDist_ = Math.Abs(GetPointToPointDist(MilPts[4], PtNow) - circleRegion.dR);
                circleRegion.dRmin = circleRegion.dR - dDist_;
                circleRegion.dRmax = circleRegion.dR + dDist_;
                if (circleRegion.dRmin <= 0) circleRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawCircle(MilPts[4], nCircleCenterSize, nCircleCenterSize);
                DrawCircle(MilPts[4], circleRegion.dR, circleRegion.dR);

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCircle(MilPts[4], circleRegion.dRmin, circleRegion.dRmin);
                DrawCircle(MilPts[4], circleRegion.dRmax, circleRegion.dRmax);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(arcRegion.ptCenter, 0, arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, 0, arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);
            }
            if (nPtIndex == 3)
            {
                double dDist_ = Math.Abs(GetPointToPointDist(circleRegion.ptCenter, MilPts[3]) - circleRegion.dR);
                circleRegion.dRmin = circleRegion.dR - dDist_;
                circleRegion.dRmax = circleRegion.dR + dDist_;
                if (circleRegion.dRmin <= 0) circleRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCircle(circleRegion.ptCenter, circleRegion.dR, circleRegion.dR);

                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawCircle(circleRegion.ptCenter, nCircleCenterSize, nCircleCenterSize);
                DrawCircle(circleRegion.ptCenter, circleRegion.dRmin, circleRegion.dRmin);
                DrawCircle(circleRegion.ptCenter, circleRegion.dRmax, circleRegion.dRmax);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(arcRegion.ptCenter, 0, arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, 0, arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                nPtIndex = -2;
            }
        }
        void DrawEllipse()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);// M_ROTATABLE 
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_DEFAULT, MIL.M_AXIS_ALIGNED_ELLIPSE);
            }
        }
        void DrawEllipseArc()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_DEFAULT, MIL.M_ARC_THREE_POINTS);
            }
        }
        void DrawRect()
        {
            if (nPtIndex == 0)
            {
                MIL.MdispControl(show.MilDisplay, MIL.M_ROI_DEFINE, MIL.M_START);
                MIL.MdispControl(show.MilDisplay, MIL.M_ROI_SHOW, MIL.M_ENABLE);
                nPtIndex = -20;
            }
            if (nPtIndex == 1)
            {
                bOnDraw = false;
            }
        }
        void DrawRectAngle()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);// M_ROTATABLE  M_AXIS_ALIGNED_RECT 
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_RECT, MIL.M_DEFAULT, MIL.M_AXIS_ALIGNED_RECT);
            }
        }
        void DrawLine()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_LINE, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawPolyline()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_POLYLINE, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawPolygon()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_POLYGON, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawOnEnd()
        {
            if (drawType == DRAW_TYPE.DRAW_NONE)
                return;
            if (drawType == DRAW_TYPE.DRAW_ARC_REGION)
                return;
            if (drawType == DRAW_TYPE.DRAW_CIRCLE_REGION)
                return;
            if (drawType == DRAW_TYPE.DRAW_MASK)
                return;

            ClearGraphic();
            if (drawType == DRAW_TYPE.DRAW_ARC)
                DrawArc(arc);
            if (drawType == DRAW_TYPE.DRAW_CIRCLE)
                DrawCircle(circle);
            if (drawType == DRAW_TYPE.DRAW_RECT)
                DrawRect(rect);
            if (drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
                DrawRect(rectAngle);
            if (drawType == DRAW_TYPE.DRAW_LINE)
                DrawLine(MilPts[0], MilPts[1]);
            if (drawType == DRAW_TYPE.DRAW_POLYLINE)
                DrawPolyline(polyLine);
            if (drawType == DRAW_TYPE.DRAW_POLYGON)
                DrawPolygon(polyLine);
            if (drawType == DRAW_TYPE.DRAW_ELLIPSE)
                DrawCircle(ellipse);
            //if (drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
            //    DrawArc(ellipseArc);
        }

        public void CallBackiInquire(MIL_ID MilGraphList, MIL_INT nLabel)
        {
            //if (bOnDraw == false) return;
            if (drawType == DRAW_TYPE.DRAW_ARC)
                CallBackiInquireArc(MilGraphList, nLabel, ref arc);
            //if (drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
            //    CallBackiInquireArc(MilGraphList, nLabel, ref ellipseArc);
            if (drawType == DRAW_TYPE.DRAW_CIRCLE)
                CallBackiInquireCircle(MilGraphList, nLabel, ref circle);
            if (drawType == DRAW_TYPE.DRAW_ELLIPSE)
                CallBackiInquireCircle(MilGraphList, nLabel, ref ellipse);
            if (drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
                CallBackiInquireRectAngle(MilGraphList, nLabel, ref rectAngle);
            if (drawType == DRAW_TYPE.DRAW_LINE
                || drawType == DRAW_TYPE.DRAW_POLYLINE
                || drawType == DRAW_TYPE.DRAW_POLYGON)
                CallBackiInquireMultiPts(MilGraphList, nLabel);
        }
        void CallBackiInquireArc(MIL_ID MilGraphList, MIL_INT nLabel, ref Arc arc)
        {
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE_START, ref arc.AngleS);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE_END, ref arc.AngleE);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_CENTER_X, ref arc.ptCenter.x);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_CENTER_Y, ref arc.ptCenter.y);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, ref arc.dRx);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_Y, ref arc.dRy);
        }
        void CallBackiInquireCircle(MIL_ID MilGraphList, MIL_INT nLabel, ref Circle circle)
        {
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_CENTER_X, ref circle.ptCenter.x);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_CENTER_Y, ref circle.ptCenter.y);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, ref circle.dRx);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_Y, ref circle.dRy);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE, ref circle.Angle);
        }
        void CallBackiInquireRectAngle(MIL_ID MilGraphList, MIL_INT nLabel, ref RectAngle rectAngle)
        {
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE, ref rectAngle.Angle);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref rectAngle.ptCenter.x);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref rectAngle.ptCenter.y);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RECTANGLE_WIDTH, ref rectAngle.Width);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RECTANGLE_HEIGHT, ref rectAngle.Height);
        }
        void CallBackiInquireMultiPts(MIL_ID MilGraphList, MIL_INT nLabel)
        {
            MIL_INT MilNum = 0;
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_NUMBER_OF_SUB_ELEMENTS + MIL.M_TYPE_MIL_INT, ref MilNum);
            polyLine = new MilPoint[(int)MilNum];
            for (int i = 0; i < MilNum; i++)
            {
                MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), i, MIL.M_POSITION_X, ref polyLine[i].x);
                MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), i, MIL.M_POSITION_Y, ref polyLine[i].y);
            }
        }

        public void DrawLine(MilPoint PtS, MilPoint PtE)
        {
            MIL.MgraLine(show.MilGraphContext, show.MilGraphList, PtS.x, PtS.y, PtE.x, PtE.y);
        }
        public void DrawVector(MilPoint PtS, MilPoint PtE)
        {
            double[] dSptX = new double[1] { PtS.x };
            double[] dSptY = new double[1] { PtS.y };
            double[] dEptX = new double[1] { PtE.x - PtS.x };
            double[] dEptY = new double[1] { PtE.y - PtS.y };
            MIL.MgraVectors(show.MilGraphContext, show.MilGraphList, 1, dSptX, dSptY, dEptX, dEptY, MIL.M_ABSOLUTE, MIL.M_DEFAULT, MIL.M_DEFAULT);
        }
        public void DrawArc(Arc arc)
        {
            DrawArc(arc.ptCenter, arc.dRx, arc.dRy, arc.AngleS, arc.AngleE);
        }
        public void DrawArc(MilPoint PtCenter, double dRx, double dRy, double dAngleS, double dAngleE)
        {
            MIL.MgraArc(show.MilGraphContext, show.MilGraphList, PtCenter.x, PtCenter.y, dRx, dRy, dAngleS, dAngleE);
        }
        public void DrawCircle(Circle circle)
        {
            DrawCircle(circle.ptCenter, circle.dRx, circle.dRy, circle.Angle);
        }
        public void DrawCircle(MilPoint PtCenter, double dRx, double dRy, double dAngle = 0)
        {
            MIL.MgraArcAngle(show.MilGraphContext, show.MilGraphList, PtCenter.x, PtCenter.y, dRx, dRy, 0, 360, dAngle, MIL.M_CONTOUR);
        }
        public void DrawRect(Rect rect)
        {
            DrawRect(rect.ptTL, rect.ptDR);
        }
        public void DrawRect(RectAngle rectAngle)
        {
            DrawRect(rectAngle.ptCenter, rectAngle.Width, rectAngle.Height, rectAngle.Angle);
        }
        public void DrawRect(MilPoint ptTL, MilPoint ptDR, double dAngle = 0)
        {
            MIL.MgraRectAngle(show.MilGraphContext, show.MilGraphList,
                (ptDR.x + ptTL.x) / 2,
                (ptDR.y + ptTL.y) / 2,
                Math.Abs(ptDR.x - ptTL.x),
                Math.Abs(ptDR.y - ptTL.y),
                dAngle, MIL.M_CENTER_AND_DIMENSION);
        }
        public void DrawRect(MilPoint ptCL, double dW, double dH, double dAngle = 0)
        {
            MIL.MgraRectAngle(show.MilGraphContext, show.MilGraphList, ptCL.x, ptCL.y, dW, dH, dAngle, MIL.M_CENTER_AND_DIMENSION);
        }
        public void DrawPolyline(MilPoint[] pts)
        {
            int nLen = pts.Length;
            double[] dx = new double[nLen];
            double[] dy = new double[nLen];
            for (int i = 0; i < nLen; i++)
            {
                dx[i] = pts[i].x;
                dy[i] = pts[i].y;
            }
            MIL.MgraLines(show.MilGraphContext, show.MilGraphList, nLen, dx, dy, MIL.M_NULL, MIL.M_NULL, MIL.M_POLYLINE);
        }
        public void DrawPolygon(MilPoint[] pts)
        {
            int nLen = pts.Length;
            double[] dx = new double[nLen];
            double[] dy = new double[nLen];
            for (int i = 0; i < nLen; i++)
            {
                dx[i] = pts[i].x;
                dy[i] = pts[i].y;
            }
            MIL.MgraLines(show.MilGraphContext, show.MilGraphList, nLen, dx, dy, MIL.M_NULL, MIL.M_NULL, MIL.M_POLYGON);
        }
        public void ClearGraphic()
        {
            MIL.MbufClear(MilImageMask, MilBackColor);
            AlphaBlend(show.MilImage, MilOverlay, MilImageMask, MilBackColor, (int)MilTransparentColor, nMaskAlpha);
            if (show.MilGraphList != MIL.M_NULL)
            {
                MIL.MgraClear(show.MilGraphContext, show.MilGraphList);
            }
        }

        public void SetMaskBackColor(MIL_INT color)
        {
            MilBackColor = color;
            MIL.MbufClear(MilImageMask, MilBackColor);
        }
        public void SetMaskForeColor(MIL_INT color)
        {
            MilForeColor = color;
        }
        public void SetPenSize(int nSize)
        {
            nMaskHalfPenSize = nSize;
        }
        public void SetAlpha(int nalpha)
        {
            if (0 < nalpha && nalpha < 256)
                nMaskAlpha = nalpha;

            if (bOnDraw)
                AlphaBlend(show.MilImage, MilOverlay, MilImageMask, MilBackColor, (int)MilTransparentColor, nMaskAlpha);
        }
        void AlphaBlend(MIL_ID MilDisplayedImage, MIL_ID MilOverlay, MIL_ID MilUserOverlay, MIL_INT UserTransparentColor, int OverlayTransparentColor, MIL_INT Alpha)
        {
            if (Alpha > 0)
            {
                MIL.MimArithMultiple(MilDisplayedImage, 256 - Alpha, MilUserOverlay, Alpha, 256,
                   MilOverlay, MIL.M_MULTIPLY_ACCUMULATE_2, MIL.M_DEFAULT);

                MIL.MbufClearCond(MilOverlay,
                    MIL.M_RGB888_R(OverlayTransparentColor),
                    MIL.M_RGB888_G(OverlayTransparentColor),
                    MIL.M_RGB888_B(OverlayTransparentColor),
                    MilUserOverlay, MIL.M_EQUAL, UserTransparentColor);
            }
            else
                MIL.MbufClear(MilOverlay, OverlayTransparentColor);
        }

        void InitMask()
        {
            MilOverlay = (MIL_ID)MIL.MdispInquire(show.MilDisplay, MIL.M_OVERLAY_ID, MIL.M_NULL);
            MilImageMask = MIL.MbufAllocColor(
                show.MilSystem, 3,
                show.MilImageSizeX,
                show.MilImageSizeY,
                8 + MIL.M_UNSIGNED,
                MIL.M_IMAGE + MIL.M_PROC + MIL.M_BGR32 + MIL.M_PACKED,
                MIL.M_NULL);
            MilTransparentColor = MIL.MdispInquire(show.MilDisplay, MIL.M_TRANSPARENT_COLOR, MIL.M_NULL);

            MIL.MbufClear(MilImageMask, MilBackColor);
            AlphaBlend(show.MilImage, MilOverlay, MilImageMask, MilBackColor, (int)MilTransparentColor, nMaskAlpha);
        }
        public MIL_ID GetMask(String sFullPath = "")
        {
            if (sFullPath.ToLower() == "auto")
            {
                MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE);
                MIL.MbufSave(MIL.M_INTERACTIVE, MilImageMask);
                MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE);
            }
            else if (sFullPath != "")
                MIL.MbufSave(sFullPath, MilImageMask);

            return MilImageMask;
        }
        void DrawMask(MIL_ID EventID)
        {
            if (drawType == DRAW_TYPE.DRAW_MASK)
            {
                MIL_INT CombinationKeys = 0;
                MIL.MdispGetHookInfo(EventID, MIL.M_COMBINATION_KEYS, ref CombinationKeys);

                if (CombinationKeys == MIL.M_MOUSE_LEFT_BUTTON)
                    DrawMask(show.MilImage, MilOverlay, MilImageMask, (int)PtNow.x, (int)PtNow.y, nMaskHalfPenSize, MilBackColor, (int)MilForeColor, nMaskAlpha);
                else if (CombinationKeys == MIL.M_MOUSE_RIGHT_BUTTON)
                    DrawMask(show.MilImage, MilOverlay, MilImageMask, (int)PtNow.x, (int)PtNow.y, nMaskHalfPenSize, MilBackColor, (int)MilBackColor, nMaskAlpha);
            }
        }
        void DrawMask(MIL_ID MilDisplayedImage, MIL_ID MilOverlay, MIL_ID MilUserOverlay, int mPosX, int nPosY, int nHalfSize, MIL_INT nBackColor, int nForeColor, int nAlpha)
        {
            MIL.MgraColor(show.MilGraphContext, nForeColor);
            MIL.MgraArcFill(show.MilGraphContext, MilUserOverlay, mPosX, nPosY, nHalfSize, nHalfSize, 0, 360);
            MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_DISABLE);

            int nOffX = mPosX - nHalfSize; if (nOffX < 0) nOffX = 0;
            int nOffY = nPosY - nHalfSize; if (nPosY < 0) nPosY = 0;
            int nSize = nHalfSize * 2;
            if (nOffX + nSize > show.MilImageSizeX)
                nSize = show.MilImageSizeX - nOffX - 1;
            if (nOffY + nSize > show.MilImageSizeY)
                nSize = show.MilImageSizeY - nOffY - 1;
            if (nSize <= 0) return;

            MIL_ID MilDisplayedImageChild = MIL.MbufChild2d(MilDisplayedImage, nOffX, nOffY, nSize, nSize, MIL.M_NULL);
            MIL_ID MilOverlayChild = MIL.MbufChild2d(MilOverlay, nOffX, nOffY, nSize, nSize, MIL.M_NULL);
            MIL_ID MilUserOverlayChild = MIL.MbufChild2d(MilUserOverlay, nOffX, nOffY, nSize, nSize, MIL.M_NULL);

            AlphaBlend(MilDisplayedImageChild, MilOverlayChild,
                MilUserOverlayChild, nBackColor,
               (int)MilTransparentColor, nAlpha);

            MIL.MbufFree(MilDisplayedImageChild);
            MIL.MbufFree(MilOverlayChild);
            MIL.MbufFree(MilUserOverlayChild);

            MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_ENABLE);
        }
    }


    public class Math__
    {
        public void LineCircleCrossPt(MilPoint PtCircleCenter, double dAngle, double dR, ref MilPoint PtCross)
        {
            double dAngle_ = D2R(dAngle);
            PtCross.x = PtCircleCenter.x + dR * Math.Cos(dAngle_);
            PtCross.y = PtCircleCenter.y + dR * Math.Sin(dAngle_);
        }
        public void GetLine(MilPoint Pt1, MilPoint Pt2, ref MilLine line)
        {
            if (Pt1.x == Pt2.x)
            {
                line.A = 1;
                line.B = 0;
                line.C = Pt1.x * (-1);
                return;
            }
            if (Pt1.y == Pt2.y)
            {
                line.A = 0;
                line.B = 1;
                line.C = Pt1.y * (-1);
                return;
            }

            double dK = (Pt2.y - Pt1.y) / (Pt2.x - Pt1.x);
            double dB = Pt1.y - dK * Pt1.x;
            line.A = dK;
            line.B = -1;
            line.C = dB;
        }
        public void GetVLine(MilPoint Pt1, MilPoint Pt2, ref MilLine line)
        {
            MilPoint Pt = new MilPoint();
            Pt.x = (Pt1.x + Pt2.x) / 2;
            Pt.y = (Pt1.y + Pt2.y) / 2;

            if (Pt1.x == Pt2.x)
            {
                line.A = 0;
                line.B = 1;
                line.C = Pt.y * (-1);
                return;
            }
            if (Pt1.y == Pt2.y)
            {
                line.A = 1;
                line.B = 0;
                line.C = Pt.x * (-1);
                return;
            }

            double dK = (Pt2.x - Pt1.x) / (Pt1.y - Pt2.y);
            double dB = Pt.y - dK * Pt.x;
            line.A = dK;
            line.B = -1;
            line.C = dB;
        }
        public void GetLineLineCrossPt(MilLine line1, MilLine line2, ref MilPoint PtCross)
        {
            if (line1.A == line2.A && line1.B == line2.B) return;
            if (line1.A == 0 && line2.A == 0) return;
            if (line1.B == 0 && line2.B == 0) return;

            if (line1.B == 0)
            {
                PtCross.x = line1.C / line1.A * (-1);
                PtCross.y = (line2.A * PtCross.x + line2.C) / line2.B * (-1);
                return;
            }

            if (line2.B == 0)
            {
                PtCross.x = line2.C / line2.A * (-1);
                PtCross.y = (line1.A * PtCross.x + line1.C) / line1.B * (-1);
                return;
            }

            double dK1 = line1.Get_k();
            double dK2 = line2.Get_k();
            double dB1 = line1.Get_b();
            double dB2 = line2.Get_b();
            PtCross.x = (dB2 - dB1) / (dK1 - dK2);
            PtCross.y = dK1 * PtCross.x + dB1;
        }
        public void GetCircleCenter(MilPoint Pt1, MilPoint Pt2, MilPoint Pt3, ref MilPoint PtCenter)
        {
            MilLine line1 = new MilLine();
            MilLine line2 = new MilLine();
            GetVLine(Pt1, Pt2, ref  line1);
            GetVLine(Pt1, Pt3, ref  line2);
            GetLineLineCrossPt(line1, line2, ref PtCenter);
        }
        public double GetPointToPointDist(MilPoint Pt1, MilPoint Pt2)
        {
            return Math.Sqrt(Math.Pow(Pt2.x - Pt1.x, 2) + Math.Pow(Pt2.y - Pt1.y, 2));
        }
        public double GetAngle(MilPoint PtL, MilPoint PtC, MilPoint PtR)
        {
            MilPoint PtLN = new MilPoint();
            MilPoint PtRN = new MilPoint();
            PtLN.x = PtL.x - PtC.x;
            PtLN.y = PtL.y - PtC.y;
            PtRN.x = PtR.x - PtC.x;
            PtRN.y = PtR.y - PtC.y;


            double fA = PtLN.x * PtRN.x + PtLN.y * PtRN.y;
            double fB = Math.Sqrt(PtLN.x * PtLN.x + PtLN.y * PtLN.y);
            double fC = Math.Sqrt(PtRN.x * PtRN.x + PtRN.y * PtRN.y);
            double fRtn = fA / (fB * fC);

            return Math.Acos(fRtn);
        }
        public double R2D(double dR)
        {
            return dR / 3.1415926 * 180;
        }
        public double D2R(double dR)
        {
            return dR / 180 * 3.1415926;
        }
    }
}

 附代码 (Mil 10 2654)  - 绘制部分

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Matrox.MatroxImagingLibrary;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace MilDraw
{
    public struct MilPoint
    {
        public double x;
        public double y;
        public void CopyTo(ref MilPoint Pt)
        {
            Pt.x = x; Pt.y = y;
        }
        public MilPoint(double x, double y)
        {
            this.x = x;
            this.y = y;
        }
    }
    public struct MilSegment
    {
        public MilPoint ptS;
        public MilPoint ptE;
    }
    public struct MilLine
    {
        public double A;
        public double B;
        public double C;

        public double Get_k()
        {
            double dk = 0;
            if (B != 0)
                dk = (-1) * A / B;
            else
                dk = (-1) * A > 0 ? 0 / .0 : 0 / .0;
            return dk;
        }

        public double Get_b()
        {
            double db = 0;
            if (B != 0)
                db = (-1) * C / B;
            else
                db = (-1) * C > 0 ? 0 / .0 : 0 / .0;
            return db;
        }
    }
    public struct Rect
    {
        public MilPoint ptTL;
        public MilPoint ptDR;
    }
    public struct RectAngle
    {
        public MilPoint ptCenter;
        public double Width;
        public double Height;
        public double Angle;
    }
    public struct Arc
    {
        public MilPoint ptCenter;
        public double AngleS;
        public double AngleE;
        public double dRx;
        public double dRy;
    }
    public struct ArcRegion
    {
        public MilPoint ptCenter;
        public double AngleS;
        public double AngleE;
        public double dR;
        public double dRmin;
        public double dRmax;
    }
    public struct Circle
    {
        public MilPoint ptCenter;
        public double dRx;
        public double dRy;
        public double Angle;
    }
    public struct CircleRegion
    {
        public MilPoint ptCenter;
        public double dR;
        public double dRmin;
        public double dRmax;
    }
    public enum DRAW_TYPE
    {
        DRAW_NONE,
        DRAW_LINE,
        DRAW_RECT,
        DRAW_RECT_ANGLE,
        DRAW_CIRCLE,
        DRAW_CIRCLE_REGION,
        DRAW_ARC,
        DRAW_ARC_REGION,
        DRAW_ELLIPSE,
        //DRAW_ELLIPSE_ARC,// Mil这个绘图有Bug,会晃动
        DRAW_POLYLINE,
        DRAW_POLYGON,
        DRAW_MASK
    }


    public class MilGraphicShow
    {
        public MIL_ID MilSystem;
        public MIL_ID MilDisplay;
        public MIL_ID MilGraphList;
        public MIL_ID MilGraphContext;
        public MIL_ID MilImage;
        public int MilImageSizeX;
        public int MilImageSizeY;
        public bool MouseLeftKeyDown;
        public bool MouseRightKeyDown;
        public GCHandle thisPtr;
        public Panel panel = null;
        public MilGraphicDraw draw = null;

        public MilPoint ptRoiInImageStart;   // ROI移动时调用,起点
        public MilPoint ptRoiInImageEnd;     // ROI移动时调用,终点
        public MilPoint ptCurMousePos;       // 当前鼠标在Panel控件的像素坐标
        public MilPoint ptCurPixelPos;       // 当前鼠标缩放到原图中的实时像素坐标
        public MilPoint ptPixelBtnLDown;     // 当前鼠标左键点下放到原图像素坐标
        public MilPoint ptPixelBtnLUp;       // 当前鼠标左键抬起放到原图像素坐标

        // 托管函数句柄
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseMoveHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseMoveHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseLeftKeyDownHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseLeftKeyDownHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseLeftKeyUpHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseLeftKeyUpHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseRightKeyDownHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseRightKeyDownHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR MouseRightKeyUpHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(MouseRightKeyUpHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR ROIChangeEndHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(ROIChangeEndHookFunc);
        public static MIL_DISP_HOOK_FUNCTION_PTR ROIChangeHookFuncPtr = new MIL_DISP_HOOK_FUNCTION_PTR(ROIChangeHookFunc);
        public static MIL_GRA_HOOK_FUNCTION_PTR GraHookFuncPtr = new MIL_GRA_HOOK_FUNCTION_PTR(GraHookFunc);

        public MilGraphicShow(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDispImage, Panel panel_)
        {
            MilGraphList = MIL.M_NULL;
            MilGraphContext = MIL.M_NULL;
            MilImage = MIL.M_NULL;
            thisPtr = GCHandle.Alloc(this);

            if (MilDisplay != MIL.M_NULL && MilSystem != MIL.M_NULL)
            {
                this.MilSystem = MilSystem;
                this.MilDisplay = MilDisplay;
                this.MilImage = MilDispImage;
                this.panel = panel_;
                MilImageSizeX = (int)MIL.MbufInquire(MilImage, MIL.M_SIZE_X, MIL.M_NULL);
                MilImageSizeY = (int)MIL.MbufInquire(MilImage, MIL.M_SIZE_Y, MIL.M_NULL);

                if (panel_.Handle != IntPtr.Zero && MilDispImage != MIL.M_NULL)
                {
                    MIL.MgraAlloc(MilSystem, ref MilGraphContext);
                    MIL.MdispSelectWindow(MilDisplay, MilDispImage, panel_.Handle);
                    MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref MilGraphList);
                    MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphList);
                }
                MIL.MdispControl(MilDisplay, MIL.M_CENTER_DISPLAY, MIL.M_ENABLE);
                MIL.MdispControl(MilDisplay, MIL.M_SCALE_DISPLAY, MIL.M_ENABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_USE, MIL.M_ENABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_CURSOR_CHANGE, MIL.M_ENABLE);

                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_MOVE, MouseMoveHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_DOWN, MouseLeftKeyDownHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_UP, MouseLeftKeyUpHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_RIGHT_BUTTON_DOWN, MouseRightKeyDownHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_RIGHT_BUTTON_UP, MouseRightKeyUpHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE_END, ROIChangeEndHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE, ROIChangeHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MgraHookFunction(MilGraphList, MIL.M_GRAPHIC_MODIFIED, GraHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

            }
        }
        public void MilFree()
        {
            if (MilDisplay != MIL.M_NULL)
            {
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_MOVE + MIL.M_UNHOOK, MouseMoveHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_DOWN + MIL.M_UNHOOK, MouseLeftKeyDownHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_MOUSE_LEFT_BUTTON_UP + MIL.M_UNHOOK, MouseLeftKeyUpHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE_END + MIL.M_UNHOOK, ROIChangeEndHookFuncPtr, GCHandle.ToIntPtr(thisPtr));
                MIL.MdispHookFunction(MilDisplay, MIL.M_ROI_CHANGE + MIL.M_UNHOOK, ROIChangeHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

                MIL.MgraHookFunction(MilGraphList, MIL.M_GRAPHIC_MODIFIED + MIL.M_UNHOOK, GraHookFuncPtr, GCHandle.ToIntPtr(thisPtr));

                MIL.MdispControl(MilDisplay, MIL.M_CENTER_DISPLAY, MIL.M_DISABLE);
                MIL.MdispControl(MilDisplay, MIL.M_SCALE_DISPLAY, MIL.M_DISABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_USE, MIL.M_DISABLE);
                MIL.MdispControl(MilDisplay, MIL.M_MOUSE_CURSOR_CHANGE, MIL.M_DISABLE);
            }

            if (MilGraphList != MIL.M_NULL)
            {
                MIL.MgraFree(MilGraphList);
                MilGraphList = MIL.M_NULL;
            }

            if (MilGraphContext != MIL.M_NULL)
            {
                MIL.MgraFree(MilGraphContext);
                MilGraphContext = MIL.M_NULL;
            }

        }

        static MIL_INT MouseMoveHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_INT px = 0;
            MIL_INT py = 0;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_X, ref px); graphic.ptCurMousePos.x = px;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_Y, ref py); graphic.ptCurMousePos.y = py;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptCurPixelPos.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptCurPixelPos.y);
            if (graphic.draw != null)
                graphic.draw.MouseMove(EventID);

            return 0;
        }
        static MIL_INT MouseLeftKeyDownHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            graphic.MouseLeftKeyDown = true;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLDown.y);
            if (graphic.draw != null)
                graphic.draw.BtnLDown(EventID);
            return 0;
        }
        static MIL_INT MouseLeftKeyUpHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLUp.y);
            if (graphic.draw != null)
                graphic.draw.BtnLUp(EventID);
            graphic.MouseLeftKeyDown = false;

            return 0;
        }
        static MIL_INT MouseRightKeyDownHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            graphic.MouseRightKeyDown = true;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLDown.y);
            if (graphic.draw != null)
                graphic.draw.BtnRDown(EventID);
            return 0;
        }
        static MIL_INT MouseRightKeyUpHookFunc(MIL_INT HookType, MIL_ID EventID, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref graphic.ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref graphic.ptPixelBtnLUp.y);
            if (graphic.draw != null)
                graphic.draw.BtnRUp(EventID);
            graphic.MouseRightKeyDown = false;

            return 0;
        }
        static MIL_INT ROIChangeEndHookFunc(MIL_INT HookType, MIL_ID MilEvent, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_ID DisplayID = graphic.MilDisplay;
            graphic.ptRoiInImageStart.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_X, MIL.M_NULL);
            graphic.ptRoiInImageStart.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_Y, MIL.M_NULL);
            graphic.ptRoiInImageEnd.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_X, MIL.M_NULL) + graphic.ptRoiInImageStart.x;
            graphic.ptRoiInImageEnd.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_Y, MIL.M_NULL) + graphic.ptRoiInImageStart.y;

            if (graphic.draw != null)
            {
                graphic.ptRoiInImageStart.CopyTo(ref graphic.draw.rect.ptTL);
                graphic.ptRoiInImageEnd.CopyTo(ref graphic.draw.rect.ptDR);
            }
            return 0;
        }
        static MIL_INT ROIChangeHookFunc(MIL_INT HookType, MIL_ID MilEvent, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_ID DisplayID = graphic.MilDisplay;
            graphic.ptRoiInImageStart.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_X, MIL.M_NULL);
            graphic.ptRoiInImageStart.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_OFFSET_Y, MIL.M_NULL);
            graphic.ptRoiInImageEnd.x = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_X, MIL.M_NULL) + graphic.ptRoiInImageStart.x;
            graphic.ptRoiInImageEnd.y = MIL.MdispInquire(DisplayID, MIL.M_ROI_BUFFER_SIZE_Y, MIL.M_NULL) + graphic.ptRoiInImageStart.y;

            if (graphic.draw != null)
            {
                graphic.ptRoiInImageStart.CopyTo(ref graphic.draw.rect.ptTL);
                graphic.ptRoiInImageEnd.CopyTo(ref graphic.draw.rect.ptDR);
            }

            return 0;
        }
        static MIL_INT GraHookFunc(MIL_INT HookType, MIL_ID EventId, IntPtr UserDataPtr)
        {
            GCHandle gch = GCHandle.FromIntPtr(UserDataPtr);
            MilGraphicShow graphic = (MilGraphicShow)gch.Target;

            MIL_INT nLabel = 0;
            MIL_INT nType = 0;
            MIL_ID MilGraphList = graphic.MilGraphList;

            MIL.MgraInquireList(graphic.MilGraphList, MIL.M_LIST, MIL.M_DEFAULT, MIL.M_LAST_LABEL, ref nLabel);
            if (nLabel <= 0 || nLabel >= 100) return 0;

            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_GRAPHIC_TYPE, ref nType);
            if (graphic.draw != null)
                graphic.draw.CallBackiInquire(MilGraphList, nLabel);

            return 0;
        }

        public void DispZoom(double ZoomFactorToApplyX, double ZoomFactorToApplyY)
        {
            MIL.MdispZoom(MilDisplay, ZoomFactorToApplyX, ZoomFactorToApplyY);
        }
        public void DispZoomOut()
        {
            if (MilDisplay != MIL.M_NULL)
            {
                double ZoomX = 1, ZoomY = 1;
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_X, ref ZoomX);
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_Y, ref ZoomY);

                if ((ZoomX >= 0.125) && (ZoomY >= 0.125))
                {
                    ZoomX /= 1.5;
                    ZoomY /= 1.5;
                }
                DispZoom(ZoomX, ZoomY);
            }
        }
        public void DispZoomIn()
        {
            if (MilDisplay != MIL.M_NULL)
            {
                double ZoomX = 1, ZoomY = 1;
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_X, ref ZoomX);
                MIL.MdispInquire(MilDisplay, MIL.M_ZOOM_FACTOR_Y, ref ZoomY);

                if ((ZoomX <= 8) && (ZoomY <= 8))
                {
                    ZoomX *= 1.5;
                    ZoomY *= 1.5;
                }
                DispZoom(ZoomX, ZoomY);
            }
        }
        public void DispFit()
        {
            double dX = panel.Width * 1.0 / MIL.MbufInquire(MilImage, MIL.M_SIZE_X, MIL.M_NULL);
            double dY = panel.Height * 1.0 / MIL.MbufInquire(MilImage, MIL.M_SIZE_Y, MIL.M_NULL);
            double dF = dX < dY ? dX : dY;
            DispZoom(dF, dF);
        }
        public void DispMouseUse(bool bEnable)
        {
            MIL.MdispControl(MilDisplay, MIL.M_MOUSE_USE, bEnable ? MIL.M_ENABLE : MIL.M_DISABLE);
        }
    }


    public class MilGraphicDraw : Math__
    {
        MilGraphicShow show = null;
        public DRAW_TYPE drawType = DRAW_TYPE.DRAW_NONE;

        int nCircleCenterSize = 5;
        int nPtIndex = -2;
        bool bOnDraw = false;
        bool bExitThr = false;

        public int nMaskHalfPenSize = 10;
        public int nMaskAlpha = 100;  // 混合浓度
        MIL_ID MilBlendImage = 0;   // Mil的绘图图层
        MIL_ID MilImageMask = 0; // 实际绘制的图片(Mask)
        MIL_INT MilBackColor = 0;  // 背景色
        MIL_INT MilForeColor = 0;  // 前景色
        MIL_INT MilTransparentColor = 0;  // Mil计算出的透明颜色存放 ID

        MilPoint PtNow = new MilPoint();
        MilPoint PtNowLast = new MilPoint();
        MilPoint ptPixelBtnLDown = new MilPoint();
        MilPoint ptPixelBtnLUp = new MilPoint();
        MilPoint[] MilPts = new MilPoint[20];
        Stopwatch DrawInterval = Stopwatch.StartNew();

        public MilSegment segment = new MilSegment();
        public MilPoint[] polyLine = new MilPoint[10];
        public Rect rect = new Rect();
        public RectAngle rectAngle;
        public Arc arc = new Arc();
        public ArcRegion arcRegion = new ArcRegion();
        public Circle circle = new Circle();
        public CircleRegion circleRegion = new CircleRegion();
        public Arc ellipseArc = new Arc();
        public Circle ellipse = new Circle();

        public MilGraphicDraw(MilGraphicShow show_)
        {
            show = show_;
            show.draw = this;

            InitMask();
            Thread thr = new Thread(thrDraw);
            thr.IsBackground = true;
            thr.Start();
        }
        public void MilFree()
        {
            show.draw = null;
            bExitThr = true;

            if (MilImageMask != 0)
                MIL.MbufFree(MilImageMask);
        }

        public void SetDrawType(DRAW_TYPE type)
        {
            if (bOnDraw == false)
                drawType = type;
        }
        public void SetDrawColor(double MilColor)
        {
            MIL.MgraColor(show.MilGraphContext, MilColor);
        }

        public void MouseMove(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref PtNow.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref PtNow.y);

            DrawMask(EventID);
        }
        public void BtnLDown(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLDown.y);

            if (drawType == DRAW_TYPE.DRAW_RECT)
                nPtIndex = 0;
            DrawMask(EventID);
        }
        public void BtnLUp(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLUp.y);

            if (nPtIndex >= 0 && nPtIndex <= 9 && GetPointToPointDist(ptPixelBtnLUp, MilPts[nPtIndex]) >= 5)
            { nPtIndex++; ptPixelBtnLUp.CopyTo(ref MilPts[nPtIndex]); }
            if (nPtIndex == -2)
                nPtIndex++;
            if (nPtIndex == -1 && ptPixelBtnLUp.x * ptPixelBtnLUp.y > 0)
            { ptPixelBtnLUp.CopyTo(ref MilPts[0]); nPtIndex++; }
            if (drawType == DRAW_TYPE.DRAW_RECT && nPtIndex < -10)
                nPtIndex = 1;
        }
        public void BtnRDown(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLDown.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLDown.y);

            DrawMask(EventID);
        }
        public void BtnRUp(MIL_ID EventID)
        {
            if (bOnDraw == false) return;
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_X, ref ptPixelBtnLUp.x);
            MIL.MdispGetHookInfo(EventID, MIL.M_MOUSE_POSITION_BUFFER_Y, ref ptPixelBtnLUp.y);


        }
        public void DrawStart()
        {
            if (drawType != DRAW_TYPE.DRAW_MASK)
                ClearGraphic();
            bOnDraw = true;
            nPtIndex = -2;
        }
        public void DrawEnd()
        {
            bOnDraw = false;
            MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_DISABLE);
            MIL.MdispControl(show.MilDisplay, MIL.M_ROI_DEFINE, MIL.M_STOP);
            MIL.MdispControl(show.MilDisplay, MIL.M_ROI_SHOW, MIL.M_DISABLE);
            MIL.MdispControl(show.MilDisplay, MIL.M_ROI_RESET, MIL.M_DEFAULT);

            DrawOnEnd();
        }

        void thrDraw()
        {
            while (bExitThr == false)
            {
                Thread.Sleep(10);
                if (bOnDraw == false) continue;
                if (DrawInterval.ElapsedMilliseconds <= 50) continue;
                if (nPtIndex < 0 || nPtIndex > 9) continue;
                if (GetPointToPointDist(PtNow, ptPixelBtnLUp) <= 1) continue;
                if (GetPointToPointDist(PtNow, PtNowLast) <= 1) continue;
                if (drawType == DRAW_TYPE.DRAW_NONE) continue;

                DrawInterval.Restart();
                PtNow.CopyTo(ref PtNowLast);

                MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_DISABLE);
                if (drawType == DRAW_TYPE.DRAW_ARC)
                    DrawArc();
                if (drawType == DRAW_TYPE.DRAW_ARC_REGION)
                    DrawArcRegion();
                if (drawType == DRAW_TYPE.DRAW_CIRCLE)
                    DrawCircle();
                if (drawType == DRAW_TYPE.DRAW_CIRCLE_REGION)
                    DrawCircleRegion();
                if (drawType == DRAW_TYPE.DRAW_RECT)
                    DrawRect();
                if (drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
                    DrawRectAngle();
                if (drawType == DRAW_TYPE.DRAW_LINE)
                    DrawLine();
                if (drawType == DRAW_TYPE.DRAW_POLYLINE)
                    DrawPolyline();
                if (drawType == DRAW_TYPE.DRAW_POLYGON)
                    DrawPolygon();
                if (drawType == DRAW_TYPE.DRAW_ELLIPSE)
                    DrawEllipse();
                //if (drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
                //    DrawEllipseArc();
                MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_ENABLE);
            }
        }
        void DrawArc()
        {
            ClearGraphic();

            if (nPtIndex == 0)
            {
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawLine(MilPts[0], PtNow);
                arc.AngleS = 0;
            }
            if (nPtIndex == 1)
            {
                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                MilPoint PtTmp = new MilPoint();
                MilLine line = new MilLine();
                GetLine(MilPts[0], MilPts[1], ref line);
                bool bStartPt = false;

                if (line.A != 0)
                {
                    double dX = (line.B * PtNow.y + line.C) / line.A * (-1);
                    bStartPt = dX > PtNow.x;//true=上点是起点  false=下点是起点

                    // 确定弧绘制起点和终点
                    if (bStartPt == (MilPts[0].y > MilPts[1].y))
                    {
                        MilPts[1].CopyTo(ref PtS);
                        MilPts[0].CopyTo(ref PtE);
                    }
                    else
                    {
                        MilPts[0].CopyTo(ref PtS);
                        MilPts[1].CopyTo(ref PtE);
                    }
                }
                else
                {
                    MilPts[1].y += 0.1;
                    return;
                }
                GetCircleCenter(MilPts[0], MilPts[1], PtNow, ref MilPts[4]);
                MilPts[4].CopyTo(ref PtTmp); PtTmp.x = 10000;

                // 计算角度
                arc.AngleS = R2D(GetAngle(PtS, MilPts[4], PtTmp));
                arc.AngleE = R2D(GetAngle(PtE, MilPts[4], PtTmp));
                if (PtS.y > MilPts[4].y) arc.AngleS = 360 - arc.AngleS;
                if (PtE.y > MilPts[4].y) arc.AngleE = 360 - arc.AngleE;

                double dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCross(MilPts[4], nCircleCenterSize);
                DrawArc(MilPts[4], dR, dR, arc.AngleS, arc.AngleE);
            }
            if (nPtIndex == 2)
            {
                MilPts[4].CopyTo(ref arc.ptCenter);
                arc.dRx = GetPointToPointDist(arc.ptCenter, MilPts[0]);
                arc.dRy = arc.dRx;
                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawCross(arc.ptCenter, nCircleCenterSize);
                DrawArc(arc.ptCenter, arc.dRx, arc.dRy, arc.AngleS, arc.AngleE);

                nPtIndex = -2;
            }

        }
        void DrawArcRegion()
        {
            ClearGraphic();

            if (nPtIndex == 0)
            {
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawLine(MilPts[0], PtNow);
                arcRegion.AngleS = 0;
            }
            if (nPtIndex == 1)
            {
                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                MilPoint PtTmp = new MilPoint();
                MilLine line = new MilLine();
                GetLine(MilPts[0], MilPts[1], ref line);
                bool bStartPt = false;

                if (line.A != 0)
                {
                    double dX = (line.B * PtNow.y + line.C) / line.A * (-1);
                    bStartPt = dX > PtNow.x;//true=上点是起点  false=下点是起点

                    // 确定弧绘制起点和终点
                    if (bStartPt == (MilPts[0].y > MilPts[1].y))
                    {
                        MilPts[1].CopyTo(ref PtS);
                        MilPts[0].CopyTo(ref PtE);
                    }
                    else
                    {
                        MilPts[0].CopyTo(ref PtS);
                        MilPts[1].CopyTo(ref PtE);
                    }
                }
                else
                {
                    MilPts[1].y += 0.1;
                    return;
                }
                GetCircleCenter(MilPts[0], MilPts[1], PtNow, ref MilPts[4]);
                MilPts[4].CopyTo(ref PtTmp); PtTmp.x = 10000;

                // 计算角度
                arcRegion.AngleS = R2D(GetAngle(PtS, MilPts[4], PtTmp));
                arcRegion.AngleE = R2D(GetAngle(PtE, MilPts[4], PtTmp));
                if (PtS.y > MilPts[4].y) arcRegion.AngleS = 360 - arcRegion.AngleS;
                if (PtE.y > MilPts[4].y) arcRegion.AngleE = 360 - arcRegion.AngleE;

                double dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCross(MilPts[4], nCircleCenterSize);
                DrawArc(MilPts[4], dR, dR, arcRegion.AngleS, arcRegion.AngleE);
            }
            if (nPtIndex == 2)
            {
                MilPts[4].CopyTo(ref arcRegion.ptCenter);
                arcRegion.dR = GetPointToPointDist(arcRegion.ptCenter, MilPts[0]);
                double dDist_ = Math.Abs(GetPointToPointDist(arcRegion.ptCenter, PtNow) - arcRegion.dR);
                arcRegion.dRmin = arcRegion.dR - dDist_;
                arcRegion.dRmax = arcRegion.dR + dDist_;
                if (arcRegion.dRmin <= 0) arcRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawArc(arcRegion.ptCenter, arcRegion.dR, arcRegion.dR, arcRegion.AngleS, arcRegion.AngleE);
                DrawCross(arcRegion.ptCenter, nCircleCenterSize);

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmin, arcRegion.dRmin, arcRegion.AngleS, arcRegion.AngleE);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmax, arcRegion.dRmax, arcRegion.AngleS, arcRegion.AngleE);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);
            }
            if (nPtIndex == 3)
            {
                double dDist_ = Math.Abs(GetPointToPointDist(arcRegion.ptCenter, MilPts[3]) - arcRegion.dR);
                arcRegion.dRmin = arcRegion.dR - dDist_;
                arcRegion.dRmax = arcRegion.dR + dDist_;
                if (arcRegion.dRmin <= 0) arcRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawArc(arcRegion.ptCenter, arcRegion.dR, arcRegion.dR, arcRegion.AngleS, arcRegion.AngleE);
                SetDrawColor(MIL.M_COLOR_GREEN);

                DrawCross(arcRegion.ptCenter, nCircleCenterSize);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmin, arcRegion.dRmin, arcRegion.AngleS, arcRegion.AngleE);
                DrawArc(arcRegion.ptCenter, arcRegion.dRmax, arcRegion.dRmax, arcRegion.AngleS, arcRegion.AngleE);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleS * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmin, ref PtS);
                LineCircleCrossPt(arcRegion.ptCenter, arcRegion.AngleE * (-1), arcRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                nPtIndex = -2;
            }
        }
        void DrawCircle()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);// M_ROTATABLE 
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_FORCE_ASPECT_RATIO_1, MIL.M_DEFAULT);
            }
        }
        void DrawCircleRegion()
        {
            ClearGraphic();

            if (nPtIndex == 0)
            {
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawLine(MilPts[0], PtNow);
            }
            if (nPtIndex == 1)
            {
                GetCircleCenter(MilPts[0], MilPts[1], PtNow, ref MilPts[4]);
                double dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCross(MilPts[4], nCircleCenterSize);
                DrawCircle(MilPts[4], dR, dR);
            }
            if (nPtIndex == 2)
            {
                MilPts[4].CopyTo(ref circleRegion.ptCenter);
                circleRegion.dR = GetPointToPointDist(MilPts[4], MilPts[0]);
                double dDist_ = Math.Abs(GetPointToPointDist(MilPts[4], PtNow) - circleRegion.dR);
                circleRegion.dRmin = circleRegion.dR - dDist_;
                circleRegion.dRmax = circleRegion.dR + dDist_;
                if (circleRegion.dRmin <= 0) circleRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawCross(MilPts[4], nCircleCenterSize);
                DrawCircle(MilPts[4], circleRegion.dR, circleRegion.dR);

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCircle(MilPts[4], circleRegion.dRmin, circleRegion.dRmin);
                DrawCircle(MilPts[4], circleRegion.dRmax, circleRegion.dRmax);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(circleRegion.ptCenter, 0, circleRegion.dRmin, ref PtS);
                LineCircleCrossPt(circleRegion.ptCenter, 0, circleRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);
            }
            if (nPtIndex == 3)
            {
                double dDist_ = Math.Abs(GetPointToPointDist(circleRegion.ptCenter, MilPts[3]) - circleRegion.dR);
                circleRegion.dRmin = circleRegion.dR - dDist_;
                circleRegion.dRmax = circleRegion.dR + dDist_;
                if (circleRegion.dRmin <= 0) circleRegion.dRmin = 1;

                SetDrawColor(MIL.M_COLOR_YELLOW);
                DrawCircle(circleRegion.ptCenter, circleRegion.dR, circleRegion.dR);

                SetDrawColor(MIL.M_COLOR_GREEN);
                DrawCross(circleRegion.ptCenter, nCircleCenterSize);
                DrawCircle(circleRegion.ptCenter, circleRegion.dRmin, circleRegion.dRmin);
                DrawCircle(circleRegion.ptCenter, circleRegion.dRmax, circleRegion.dRmax);

                MilPoint PtS = new MilPoint();
                MilPoint PtE = new MilPoint();
                LineCircleCrossPt(circleRegion.ptCenter, 0, circleRegion.dRmin, ref PtS);
                LineCircleCrossPt(circleRegion.ptCenter, 0, circleRegion.dRmax, ref PtE);
                DrawVector(PtS, PtE);

                nPtIndex = -2;
            }
        }
        void DrawEllipse()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);// M_ROTATABLE 
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawEllipseArc()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_ARC, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawRect()
        {
            if (nPtIndex == 0)
            {
                MIL.MdispControl(show.MilDisplay, MIL.M_ROI_DEFINE, MIL.M_START);
                MIL.MdispControl(show.MilDisplay, MIL.M_ROI_SHOW, MIL.M_ENABLE);
                nPtIndex = -20;
            }
            if (nPtIndex == 1)
            {
                bOnDraw = false;
            }
        }
        void DrawRectAngle()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);// M_ROTATABLE  M_AXIS_ALIGNED_RECT 
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_RECT, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawLine()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_LINE, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawPolyline()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_POLYLINE, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawPolygon()
        {
            if (nPtIndex == 0)
            {
                ClearGraphic();
                bOnDraw = false;
                SetDrawColor(MIL.M_COLOR_GREEN);
                MIL.MdispControl(show.MilDisplay, MIL.M_GRAPHIC_LIST_INTERACTIVE, MIL.M_ENABLE);
                MIL.MgraInteractive(show.MilGraphContext, show.MilGraphList, MIL.M_GRAPHIC_TYPE_POLYGON, MIL.M_DEFAULT, MIL.M_DEFAULT);
            }
        }
        void DrawOnEnd()
        {
            if (drawType == DRAW_TYPE.DRAW_NONE)
                return;
            if (drawType == DRAW_TYPE.DRAW_ARC_REGION)
                return;
            if (drawType == DRAW_TYPE.DRAW_CIRCLE_REGION)
                return;
            if (drawType == DRAW_TYPE.DRAW_MASK)
                return;

            ClearGraphic();
            if (drawType == DRAW_TYPE.DRAW_ARC)
                DrawArc(arc);
            if (drawType == DRAW_TYPE.DRAW_CIRCLE)
                DrawCircle(circle);
            if (drawType == DRAW_TYPE.DRAW_RECT)
                DrawRect(rect);
            if (drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
                DrawRect(rectAngle);
            if (drawType == DRAW_TYPE.DRAW_LINE)
                DrawLine(MilPts[0], MilPts[1]);
            if (drawType == DRAW_TYPE.DRAW_POLYLINE)
                DrawPolyline(polyLine);
            if (drawType == DRAW_TYPE.DRAW_POLYGON)
                DrawPolygon(polyLine);
            if (drawType == DRAW_TYPE.DRAW_ELLIPSE)
                DrawCircle(ellipse);
            //if (drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
            //    DrawArc(ellipseArc);
        }

        public void CallBackiInquire(MIL_ID MilGraphList, MIL_INT nLabel)
        {
            //if (bOnDraw == false) return;
            if (drawType == DRAW_TYPE.DRAW_ARC)
                CallBackiInquireArc(MilGraphList, nLabel, ref arc);
            //if (drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
            //    CallBackiInquireArc(MilGraphList, nLabel, ref ellipseArc);
            if (drawType == DRAW_TYPE.DRAW_CIRCLE)
                CallBackiInquireCircle(MilGraphList, nLabel, ref circle);
            if (drawType == DRAW_TYPE.DRAW_ELLIPSE)
                CallBackiInquireCircle(MilGraphList, nLabel, ref ellipse);
            if (drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
                CallBackiInquireRectAngle(MilGraphList, nLabel, ref rectAngle);
            if (drawType == DRAW_TYPE.DRAW_LINE
                || drawType == DRAW_TYPE.DRAW_POLYLINE
                || drawType == DRAW_TYPE.DRAW_POLYGON)
                CallBackiInquireMultiPts(MilGraphList, nLabel);
        }
        void CallBackiInquireArc(MIL_ID MilGraphList, MIL_INT nLabel, ref Arc arc)
        {
            //MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE_START, ref arc.AngleS);
            //MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE_END, ref arc.AngleE);
            //MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref arc.ptCenter.x);
            //MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref arc.ptCenter.y);
            //MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, ref arc.dRx);
            //MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_Y, ref arc.dRy);
        }
        void CallBackiInquireCircle(MIL_ID MilGraphList, MIL_INT nLabel, ref Circle circle)
        {
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref circle.ptCenter.x);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref circle.ptCenter.y);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_X, ref circle.dRx);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RADIUS_Y, ref circle.dRy);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE, ref circle.Angle);
        }
        void CallBackiInquireRectAngle(MIL_ID MilGraphList, MIL_INT nLabel, ref RectAngle rectAngle)
        {
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_ANGLE, ref rectAngle.Angle);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_X, ref rectAngle.ptCenter.x);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_POSITION_Y, ref rectAngle.ptCenter.y);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RECTANGLE_WIDTH, ref rectAngle.Width);
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_RECTANGLE_HEIGHT, ref rectAngle.Height);
        }
        void CallBackiInquireMultiPts(MIL_ID MilGraphList, MIL_INT nLabel)
        {
            MIL_INT MilNum = 0;
            MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), MIL.M_DEFAULT, MIL.M_NUMBER_OF_SUB_ELEMENTS + MIL.M_TYPE_MIL_INT, ref MilNum);
            polyLine = new MilPoint[(int)MilNum];
            for (int i = 0; i < MilNum; i++)
            {
                MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), i, MIL.M_POSITION_X, ref polyLine[i].x);
                MIL.MgraInquireList(MilGraphList, MIL.M_GRAPHIC_LABEL(nLabel), i, MIL.M_POSITION_Y, ref polyLine[i].y);
            }
        }

        public void DrawLine(MilPoint PtS, MilPoint PtE)
        {
            MIL.MgraLine(show.MilGraphContext, show.MilGraphList, PtS.x, PtS.y, PtE.x, PtE.y);
        }
        public void DrawVector(MilPoint PtS, MilPoint PtE)
        {
            MilPoint ptTmp1 = Rotate(PtS, PtE, 40);
            MilPoint ptTmp2 = Rotate(PtS, PtE, -40);
            double dF = 4 / GetPointToPointDist(PtS, PtE);
            ptTmp1.x = (ptTmp1.x - PtE.x) * dF + PtE.x;
            ptTmp1.y = (ptTmp1.y - PtE.y) * dF + PtE.y;
            ptTmp2.x = (ptTmp2.x - PtE.x) * dF + PtE.x;
            ptTmp2.y = (ptTmp2.y - PtE.y) * dF + PtE.y;

            double[] dSptX = new double[3] { PtS.x, ptTmp1.x, ptTmp2.x };
            double[] dSptY = new double[3] { PtS.y, ptTmp1.y, ptTmp2.y };
            double[] dEptX = new double[3] { PtE.x, PtE.x, PtE.x };
            double[] dEptY = new double[3] { PtE.y, PtE.y, PtE.y };
            MIL.MgraLines(show.MilGraphContext, show.MilGraphList, 3, dSptX, dSptY, dEptX, dEptY, MIL.M_DEFAULT);
        }
        public void DrawArc(Arc arc)
        {
            DrawArc(arc.ptCenter, arc.dRx, arc.dRy, arc.AngleS, arc.AngleE);
        }
        public void DrawArc(MilPoint PtCenter, double dRx, double dRy, double dAngleS, double dAngleE)
        {
            MIL.MgraArc(show.MilGraphContext, show.MilGraphList, PtCenter.x, PtCenter.y, dRx, dRy, dAngleS, dAngleE);
        }
        public void DrawCircle(Circle circle)
        {
            DrawCircle(circle.ptCenter, circle.dRx, circle.dRy, circle.Angle);
        }
        public void DrawCircle(MilPoint PtCenter, double dRx, double dRy, double dAngle = 0)
        {
            MIL.MgraArcAngle(show.MilGraphContext, show.MilGraphList, PtCenter.x, PtCenter.y, dRx, dRy, 0, 360, dAngle, MIL.M_CONTOUR);
        }
        public void DrawCross(MilPoint PtCenter, double dLen)
        {
            double[] dXs = new double[2] { PtCenter.x, PtCenter.x - dLen / 2 };
            double[] dYs = new double[2] { PtCenter.y - dLen / 2, PtCenter.y };
            double[] dXe = new double[2] { PtCenter.x, PtCenter.x + dLen / 2 };
            double[] dYe = new double[2] { PtCenter.y + dLen / 2, PtCenter.y };
            MIL.MgraLines(show.MilGraphContext, show.MilGraphList, 2, dXs, dYs, dXe, dYe, MIL.M_DEFAULT);
        }
        public void DrawRect(Rect rect)
        {
            DrawRect(rect.ptTL, rect.ptDR);
        }
        public void DrawRect(RectAngle rectAngle)
        {
            DrawRect(rectAngle.ptCenter, rectAngle.Width, rectAngle.Height, rectAngle.Angle);
        }
        public void DrawRect(MilPoint ptTL, MilPoint ptDR, double dAngle = 0)
        {
            MIL.MgraRectAngle(show.MilGraphContext, show.MilGraphList,
                (ptDR.x + ptTL.x) / 2,
                (ptDR.y + ptTL.y) / 2,
                Math.Abs(ptDR.x - ptTL.x),
                Math.Abs(ptDR.y - ptTL.y),
                dAngle, MIL.M_CENTER_AND_DIMENSION);
        }
        public void DrawRect(MilPoint ptCL, double dW, double dH, double dAngle = 0)
        {
            MIL.MgraRectAngle(show.MilGraphContext, show.MilGraphList, ptCL.x, ptCL.y, dW, dH, dAngle, MIL.M_CENTER_AND_DIMENSION);
        }
        public void DrawPolyline(MilPoint[] pts)
        {
            int nLen = pts.Length;
            double[] dx = new double[nLen];
            double[] dy = new double[nLen];
            for (int i = 0; i < nLen; i++)
            {
                dx[i] = pts[i].x;
                dy[i] = pts[i].y;
            }
            MIL.MgraLines(show.MilGraphContext, show.MilGraphList, nLen, dx, dy, MIL.M_NULL, MIL.M_NULL, MIL.M_POLYLINE);
        }
        public void DrawPolygon(MilPoint[] pts)
        {
            int nLen = pts.Length;
            double[] dx = new double[nLen];
            double[] dy = new double[nLen];
            for (int i = 0; i < nLen; i++)
            {
                dx[i] = pts[i].x;
                dy[i] = pts[i].y;
            }
            MIL.MgraLines(show.MilGraphContext, show.MilGraphList, nLen, dx, dy, MIL.M_NULL, MIL.M_NULL, MIL.M_POLYGON);
        }
        public void ClearGraphic()
        {
            MIL.MbufClear(MilImageMask, MilBackColor);
            AlphaBlend(show.MilImage, MilImageMask, MilBlendImage, MilBackColor, (int)MilTransparentColor, nMaskAlpha);
            if (show.MilGraphList != MIL.M_NULL)
            {
                MIL.MgraClear(show.MilGraphContext, show.MilGraphList);
            }
        }

        public void SetMaskBackColor(MIL_INT color)
        {
            MilBackColor = color;
            MIL.MbufClear(MilImageMask, MilBackColor);
        }
        public void SetMaskForeColor(MIL_INT color)
        {
            MilForeColor = color;
        }
        public void SetPenSize(int nSize)
        {
            nMaskHalfPenSize = nSize;
        }
        public void SetAlpha(int nalpha)
        {
            if (0 < nalpha && nalpha < 256)
                nMaskAlpha = nalpha;

            if (bOnDraw)
                AlphaBlend(show.MilImage, MilImageMask, MilBlendImage, MilBackColor, (int)MilTransparentColor, nMaskAlpha);
        }
        void AlphaBlend(MIL_ID MilDisplayedImage, MIL_ID MilImageMask, MIL_ID MilBlendImage, MIL_INT UserTransparentColor, int OverlayTransparentColor, MIL_INT Alpha)
        {
            if (Alpha > 0)
            {
                MIL.MimArithMultiple(MilDisplayedImage, 256 - Alpha, MilImageMask, Alpha, 256,
                   MilBlendImage, MIL.M_MULTIPLY_ACCUMULATE_2, MIL.M_DEFAULT);
            }
            else
                MIL.MbufClear(this.MilBlendImage, OverlayTransparentColor);
        }

        void InitMask()
        {
            MilBlendImage = (MIL_ID)MIL.MdispInquire(show.MilDisplay, MIL.M_OVERLAY_ID, MIL.M_NULL);
            MilImageMask = MIL.MbufAllocColor(
                show.MilSystem, 3,
                show.MilImageSizeX,
                show.MilImageSizeY,
                8 + MIL.M_UNSIGNED,
                MIL.M_IMAGE + MIL.M_PROC + MIL.M_BGR32 + MIL.M_PACKED,
                MIL.M_NULL);
            MilTransparentColor = MIL.MdispInquire(show.MilDisplay, MIL.M_TRANSPARENT_COLOR, MIL.M_NULL);

            MIL.MbufClear(MilImageMask, MilBackColor);
            AlphaBlend(show.MilImage, MilImageMask, MilBlendImage, MilBackColor, (int)MilTransparentColor, nMaskAlpha);
        }
        public MIL_ID GetMask(String sFullPath = "")
        {
            if (sFullPath.ToLower() == "auto")
            {
                MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE);
                MIL.MbufSave(MIL.M_INTERACTIVE, MilImageMask);
                MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE);
            }
            else if (sFullPath != "")
                MIL.MbufSave(sFullPath, MilImageMask);

            return MilImageMask;
        }
        void DrawMask(MIL_ID EventID)
        {
            if (drawType == DRAW_TYPE.DRAW_MASK)
            {
                MIL_INT CombinationKeys = 0;
                MIL.MdispGetHookInfo(EventID, MIL.M_COMBINATION_KEYS, ref CombinationKeys);

                if (CombinationKeys == MIL.M_MOUSE_LEFT_BUTTON)
                    DrawMask(show.MilImage, MilImageMask, MilBlendImage, (int)PtNow.x, (int)PtNow.y, nMaskHalfPenSize, MilBackColor, (int)MilForeColor, nMaskAlpha);
                else if (CombinationKeys == MIL.M_MOUSE_RIGHT_BUTTON)
                    DrawMask(show.MilImage, MilImageMask, MilBlendImage, (int)PtNow.x, (int)PtNow.y, nMaskHalfPenSize, MilBackColor, (int)MilBackColor, nMaskAlpha);
            }
        }
        void DrawMask(MIL_ID MilDisplayedImage, MIL_ID MilImageMask, MIL_ID MilBlendImage, int mPosX, int nPosY, int nHalfSize, MIL_INT nBackColor, int nForeColor, int nAlpha)
        {
            MIL.MgraColor(show.MilGraphContext, nForeColor);
            MIL.MgraArcFill(show.MilGraphContext, MilImageMask, mPosX, nPosY, nHalfSize, nHalfSize, 0, 360);
            MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_DISABLE);

            AlphaBlend(MilDisplayedImage, MilImageMask, MilBlendImage, nBackColor, (int)MilTransparentColor, nAlpha);

            MIL.MdispControl(show.MilDisplay, MIL.M_UPDATE, MIL.M_ENABLE);
        }
    }


    public class Math__
    {
        public void LineCircleCrossPt(MilPoint PtCircleCenter, double dAngle, double dR, ref MilPoint PtCross)
        {
            double dAngle_ = D2R(dAngle);
            PtCross.x = PtCircleCenter.x + dR * Math.Cos(dAngle_);
            PtCross.y = PtCircleCenter.y + dR * Math.Sin(dAngle_);
        }
        public void GetLine(MilPoint Pt1, MilPoint Pt2, ref MilLine line)
        {
            if (Pt1.x == Pt2.x)
            {
                line.A = 1;
                line.B = 0;
                line.C = Pt1.x * (-1);
                return;
            }
            if (Pt1.y == Pt2.y)
            {
                line.A = 0;
                line.B = 1;
                line.C = Pt1.y * (-1);
                return;
            }

            double dK = (Pt2.y - Pt1.y) / (Pt2.x - Pt1.x);
            double dB = Pt1.y - dK * Pt1.x;
            line.A = dK;
            line.B = -1;
            line.C = dB;
        }
        public void GetVLine(MilPoint Pt1, MilPoint Pt2, ref MilLine line)
        {
            MilPoint Pt = new MilPoint();
            Pt.x = (Pt1.x + Pt2.x) / 2;
            Pt.y = (Pt1.y + Pt2.y) / 2;

            if (Pt1.x == Pt2.x)
            {
                line.A = 0;
                line.B = 1;
                line.C = Pt.y * (-1);
                return;
            }
            if (Pt1.y == Pt2.y)
            {
                line.A = 1;
                line.B = 0;
                line.C = Pt.x * (-1);
                return;
            }

            double dK = (Pt2.x - Pt1.x) / (Pt1.y - Pt2.y);
            double dB = Pt.y - dK * Pt.x;
            line.A = dK;
            line.B = -1;
            line.C = dB;
        }
        public void GetLineLineCrossPt(MilLine line1, MilLine line2, ref MilPoint PtCross)
        {
            if (line1.A == line2.A && line1.B == line2.B) return;
            if (line1.A == 0 && line2.A == 0) return;
            if (line1.B == 0 && line2.B == 0) return;

            if (line1.B == 0)
            {
                PtCross.x = line1.C / line1.A * (-1);
                PtCross.y = (line2.A * PtCross.x + line2.C) / line2.B * (-1);
                return;
            }

            if (line2.B == 0)
            {
                PtCross.x = line2.C / line2.A * (-1);
                PtCross.y = (line1.A * PtCross.x + line1.C) / line1.B * (-1);
                return;
            }

            double dK1 = line1.Get_k();
            double dK2 = line2.Get_k();
            double dB1 = line1.Get_b();
            double dB2 = line2.Get_b();
            PtCross.x = (dB2 - dB1) / (dK1 - dK2);
            PtCross.y = dK1 * PtCross.x + dB1;
        }
        public void GetCircleCenter(MilPoint Pt1, MilPoint Pt2, MilPoint Pt3, ref MilPoint PtCenter)
        {
            MilLine line1 = new MilLine();
            MilLine line2 = new MilLine();
            GetVLine(Pt1, Pt2, ref line1);
            GetVLine(Pt1, Pt3, ref line2);
            GetLineLineCrossPt(line1, line2, ref PtCenter);
        }
        public double GetPointToPointDist(MilPoint Pt1, MilPoint Pt2)
        {
            return Math.Sqrt(Math.Pow(Pt2.x - Pt1.x, 2) + Math.Pow(Pt2.y - Pt1.y, 2));
        }
        public double GetAngle(MilPoint PtL, MilPoint PtC, MilPoint PtR)
        {
            MilPoint PtLN = new MilPoint();
            MilPoint PtRN = new MilPoint();
            PtLN.x = PtL.x - PtC.x;
            PtLN.y = PtL.y - PtC.y;
            PtRN.x = PtR.x - PtC.x;
            PtRN.y = PtR.y - PtC.y;


            double fA = PtLN.x * PtRN.x + PtLN.y * PtRN.y;
            double fB = Math.Sqrt(PtLN.x * PtLN.x + PtLN.y * PtLN.y);
            double fC = Math.Sqrt(PtRN.x * PtRN.x + PtRN.y * PtRN.y);
            double fRtn = fA / (fB * fC);

            return Math.Acos(fRtn);
        }
        public double R2D(double dR)
        {
            return dR / 3.1415926 * 180;
        }
        public double D2R(double dR)
        {
            return dR / 180 * 3.1415926;
        }

        public MilPoint Rotate(MilPoint ptRot, MilPoint ptBase, double dAngle)
        {
            double dCos = Math.Cos(D2R(dAngle));
            double dSin = Math.Sin(D2R(dAngle));

            MilPoint TmpMyPt;
            TmpMyPt.x = ptRot.x - ptBase.x;
            TmpMyPt.y = ptRot.y - ptBase.y;
            double x = dCos * TmpMyPt.x + dSin * TmpMyPt.y;
            double y = dCos * TmpMyPt.y - dSin * TmpMyPt.x;
            TmpMyPt.x = x + ptBase.x;
            TmpMyPt.y = y + ptBase.y;

            return TmpMyPt;
        }
    }
}

附代码 - Demo调用部分

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Forms;
using Matrox.MatroxImagingLibrary;

namespace MilDraw
{
    public partial class FormMain : Form
    {
        MIL_ID MilApplication;
        MIL_ID MilSystem;
        MIL_ID MilDisplay;

        MIL_ID MilImage;
        MIL_ID MilGraContext;
        MIL_ID MilGraList;

        MilGraphicShow gra = null;
        MilGraphicDraw graDraw = null;
        public FormMain()
        {
            InitializeComponent();
            MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL);

            //MIL.MbufAllocColor(MilSystem, 1, 2464, 2040, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_DISP + MIL.M_PROC, ref MilImage);
            //MIL.MbufClear(MilImage, 50);
            MIL.MbufRestore("5.jpeg", MilSystem, ref MilImage);

            MIL.MgraAlloc(MilSystem, ref MilGraContext);
            MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref MilGraList);
            MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraList);
            gra = new MilGraphicShow(MilSystem, MilDisplay, MilImage, panel1);
            gra.DispFit();
            graDraw = new MilGraphicDraw(gra);

            comboBox1.Items.Add("DRAW_NONE");
            comboBox1.Items.Add("DRAW_RECT");
            comboBox1.Items.Add("DRAW_RECT_ANGLE");
            comboBox1.Items.Add("DRAW_CIRCLE");
            comboBox1.Items.Add("DRAW_CIRCLE_REGION");
            comboBox1.Items.Add("DRAW_ARC");
            comboBox1.Items.Add("DRAW_ARC_REGION");
            comboBox1.Items.Add("DRAW_ELLIPSE");
            //comboBox1.Items.Add("DRAW_ELLIPSE_ARC");
            comboBox1.Items.Add("DRAW_POLYLINE");
            comboBox1.Items.Add("DRAW_POLYGON");
            comboBox1.Items.Add("DRAW_MASK");
            comboBox1.SelectedItem = "DRAW_NONE";

            checkBox1.Checked = true;
            checkBox6.Checked = true;
            textBox1.Text = graDraw.nMaskHalfPenSize.ToString();
            textBox2.Text = graDraw.nMaskAlpha.ToString();

            timer.Interval = 20;
            timer.Start();
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer.Stop();

            gra.MilFree();
            graDraw.MilFree();
            MIL.MbufFree(MilImage);
            MIL.MgraFree(MilGraList);
            MIL.MgraFree(MilGraContext);
            MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL);
        }


        private void button1_Click(object sender, EventArgs e)
        {
            graDraw.SetDrawType(GetDrawType());
            graDraw.DrawStart();
            EnableColorBox(false, false);

            if (GetDrawType() == DRAW_TYPE.DRAW_MASK)
                gra.DispMouseUse(false);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            graDraw.DrawEnd();
            if (graDraw.drawType == DRAW_TYPE.DRAW_MASK)
            {
                EnableColorBox(true, false);
                gra.DispMouseUse(true);
            }
        }

        DRAW_TYPE GetDrawType()
        {
            if (comboBox1.SelectedItem == "DRAW_NONE") return DRAW_TYPE.DRAW_NONE;
            if (comboBox1.SelectedItem == "DRAW_RECT") return DRAW_TYPE.DRAW_RECT;
            if (comboBox1.SelectedItem == "DRAW_RECT_ANGLE") return DRAW_TYPE.DRAW_RECT_ANGLE;
            if (comboBox1.SelectedItem == "DRAW_CIRCLE") return DRAW_TYPE.DRAW_CIRCLE;
            if (comboBox1.SelectedItem == "DRAW_CIRCLE_REGION") return DRAW_TYPE.DRAW_CIRCLE_REGION;
            if (comboBox1.SelectedItem == "DRAW_ARC") return DRAW_TYPE.DRAW_ARC;
            if (comboBox1.SelectedItem == "DRAW_ARC_REGION") return DRAW_TYPE.DRAW_ARC_REGION;
            if (comboBox1.SelectedItem == "DRAW_ELLIPSE") return DRAW_TYPE.DRAW_ELLIPSE;
            //if ( comboBox1.SelectedItem == "DRAW_ELLIPSE_ARC")return DRAW_TYPE.DRAW_ELLIPSE_ARC;
            if (comboBox1.SelectedItem == "DRAW_POLYLINE") return DRAW_TYPE.DRAW_POLYLINE;
            if (comboBox1.SelectedItem == "DRAW_POLYGON") return DRAW_TYPE.DRAW_POLYGON;
            if (comboBox1.SelectedItem == "DRAW_MASK") return DRAW_TYPE.DRAW_MASK;

            return DRAW_TYPE.DRAW_NONE;
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (gra == null) return;
            if (graDraw == null) return;

            labelTip.Text = "PtInScreen [" + gra.ptCurMousePos.x.ToString("F4") + ", " + gra.ptCurMousePos.y.ToString("F4") + "]\n";
            labelTip.Text += "PtInImage [" + gra.ptCurPixelPos.x.ToString("F4") + ", " + gra.ptCurPixelPos.y.ToString("F4") + "]";

            if (graDraw.drawType == DRAW_TYPE.DRAW_ARC)
            {
                label1.Text = "Ptc = [" + graDraw.arc.ptCenter.x.ToString("F4") + ", " + graDraw.arc.ptCenter.y.ToString("F4") + "]";
                label2.Text = "Rx = " + graDraw.arc.dRx.ToString("F4");
                label3.Text = "Ry = " + graDraw.arc.dRy.ToString("F4");
                label4.Text = "AngleS = " + graDraw.arc.AngleS.ToString("F4");
                label5.Text = "AngleE = " + graDraw.arc.AngleE.ToString("F4");
                label6.Text = "";
            }

            if (graDraw.drawType == DRAW_TYPE.DRAW_ARC_REGION)
            {
                label1.Text = "Ptc = [" + graDraw.arcRegion.ptCenter.x.ToString("F4") + ", " + graDraw.arcRegion.ptCenter.y.ToString("F4") + "]";
                label2.Text = "R = " + graDraw.arcRegion.dR.ToString("F4");
                label3.Text = "AngleS = " + graDraw.arcRegion.AngleS.ToString("F4");
                label4.Text = "AngleE = " + graDraw.arcRegion.AngleE.ToString("F4");
                label5.Text = "Rmin = " + graDraw.arcRegion.dRmin.ToString("F4");
                label6.Text = "Rmax = " + graDraw.arcRegion.dRmax.ToString("F4");
            }

            if (graDraw.drawType == DRAW_TYPE.DRAW_CIRCLE)
            {
                label1.Text = "Ptc = [" + graDraw.circle.ptCenter.x.ToString("F4") + ", " + graDraw.circle.ptCenter.y.ToString("F4") + "]";
                label2.Text = "Rx = " + graDraw.circle.dRx.ToString("F4");
                label3.Text = "Ry = " + graDraw.circle.dRy.ToString("F4");
                label4.Text = "";
                label5.Text = "";
                label6.Text = "";
            }

            if (graDraw.drawType == DRAW_TYPE.DRAW_CIRCLE_REGION)
            {
                label1.Text = "Ptc = [" + graDraw.circleRegion.ptCenter.x.ToString("F4") + ", " + graDraw.circleRegion.ptCenter.y.ToString("F4") + "]";
                label2.Text = "R = " + graDraw.circleRegion.dR.ToString("F4");
                label3.Text = "Rmin = " + graDraw.circleRegion.dRmin.ToString("F4");
                label4.Text = "Rmax = " + graDraw.circleRegion.dRmax.ToString("F4");
                label5.Text = "";
                label6.Text = "";
            }

            //if (graDraw.drawType == DRAW_TYPE.DRAW_ELLIPSE_ARC)
            //{
            //    label1.Text = "Ptc = [" + graDraw.ellipseArc.ptCenter.x.ToString("F4") + ", " + graDraw.ellipseArc.ptCenter.y.ToString("F4") + "]";
            //    label2.Text = "Rx = " + graDraw.ellipseArc.dRx.ToString("F4");
            //    label3.Text = "Ry = " + graDraw.ellipseArc.dRy.ToString("F4");
            //    label4.Text = "AngleS = " + graDraw.ellipseArc.AngleS.ToString("F4");
            //    label5.Text = "AngleE = " + graDraw.ellipseArc.AngleE.ToString("F4");
            //}

            if (graDraw.drawType == DRAW_TYPE.DRAW_ELLIPSE)
            {
                label1.Text = "Ptc = [" + graDraw.ellipse.ptCenter.x.ToString("F4") + ", " + graDraw.ellipse.ptCenter.y.ToString("F4") + "]";
                label2.Text = "Rx = " + graDraw.ellipse.dRx.ToString("F4");
                label3.Text = "Ry = " + graDraw.ellipse.dRy.ToString("F4");
                label4.Text = "Angle = " + graDraw.ellipse.Angle.ToString("F4");
                label5.Text = "";
                label6.Text = "";
            }

            if (graDraw.drawType == DRAW_TYPE.DRAW_RECT)
            {
                label1.Text = "PtTL = [" + graDraw.rect.ptTL.x.ToString("F4") + ", " + graDraw.rect.ptTL.y.ToString("F4") + "]";
                label2.Text = "PtDR = [" + graDraw.rect.ptDR.x.ToString("F4") + ", " + graDraw.rect.ptDR.y.ToString("F4") + "]";
                label3.Text = "";
                label4.Text = "";
                label5.Text = "";
                label6.Text = "";
            }

            if (graDraw.drawType == DRAW_TYPE.DRAW_RECT_ANGLE)
            {
                label1.Text = "Ptc = [" + graDraw.rectAngle.ptCenter.x.ToString("F4") + ", " + graDraw.rectAngle.ptCenter.y.ToString("F4") + "]";
                label2.Text = "Width = " + graDraw.rectAngle.Width.ToString("F4");
                label3.Text = "Height = " + graDraw.rectAngle.Height.ToString("F4");
                label4.Text = "Angle = " + graDraw.rectAngle.Angle.ToString("F4");
                label5.Text = "";
                label6.Text = "";
            }

            if (
                (graDraw.drawType == DRAW_TYPE.DRAW_LINE
                || graDraw.drawType == DRAW_TYPE.DRAW_POLYLINE
                || graDraw.drawType == DRAW_TYPE.DRAW_POLYGON))
            {
                label1.Text = "num = " + graDraw.polyLine.Length.ToString();
                if (graDraw.polyLine.Length > 0)
                    label2.Text = "Pt1 = [" + graDraw.polyLine[0].x.ToString("F4") + ", " + graDraw.polyLine[0].y.ToString("F4") + "]";
                if (graDraw.polyLine.Length > 1)
                    label3.Text = "Pt2 = [" + graDraw.polyLine[1].x.ToString("F4") + ", " + graDraw.polyLine[1].y.ToString("F4") + "]";
                if (graDraw.polyLine.Length > 2)
                    label4.Text = "Pt3 = [" + graDraw.polyLine[2].x.ToString("F4") + ", " + graDraw.polyLine[2].y.ToString("F4") + "]";
                if (graDraw.polyLine.Length > 3)
                    label5.Text = "Pt4 = [" + graDraw.polyLine[3].x.ToString("F4") + ", " + graDraw.polyLine[3].y.ToString("F4") + "]";
                if (graDraw.polyLine.Length > 4)
                    label6.Text = "Pt5 = [" + graDraw.polyLine[4].x.ToString("F4") + ", " + graDraw.polyLine[4].y.ToString("F4") + "]";
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedItem == "DRAW_MASK")
                EnableColorBox(true);
            else
                EnableColorBox(false);
        }

        void EnableColorBox(bool bEnable, bool bIsAll = true)
        {
            if (bIsAll)
            {

                checkBox1.Enabled = bEnable;
                checkBox2.Enabled = bEnable;
                checkBox3.Enabled = bEnable;
                checkBox4.Enabled = bEnable;
                checkBox5.Enabled = bEnable;
            }
            checkBox6.Enabled = bEnable;
            checkBox7.Enabled = bEnable;
        }


        int nSelForeColor = 0;
        int nSelBackColor = 0;
        MIL_INT[] MilForeColor = new MIL_INT[5] {
            MIL.M_COLOR_GREEN, 
            MIL.M_COLOR_CYAN, 
            MIL.M_COLOR_DARK_BLUE, 
            MIL.M_COLOR_YELLOW,
            MIL.M_COLOR_MAGENTA };
        MIL_INT[] MilBlackColor = new MIL_INT[2] { MIL.M_COLOR_BLACK, MIL.M_COLOR_WHITE };
        void CheckForeColor(CheckBox cBox)
        {
            if (cBox != checkBox1) checkBox1.Checked = false; else nSelForeColor = 0;
            if (cBox != checkBox2) checkBox2.Checked = false; else nSelForeColor = 1;
            if (cBox != checkBox3) checkBox3.Checked = false; else nSelForeColor = 2;
            if (cBox != checkBox4) checkBox4.Checked = false; else nSelForeColor = 3;
            if (cBox != checkBox5) checkBox5.Checked = false; else nSelForeColor = 4;

            graDraw.SetMaskForeColor(MilForeColor[nSelForeColor]);
        }

        void CheckBackColor(CheckBox cBox)
        {
            if (cBox != checkBox6) checkBox6.Checked = false; else nSelBackColor = 0;
            if (cBox != checkBox7) checkBox7.Checked = false; else nSelBackColor = 1;

            graDraw.SetMaskBackColor(MilBlackColor[nSelBackColor]);
        }

        bool bInCheck = false;
        private void CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (bInCheck) return;
            bInCheck = true;
            CheckBox cBox = (CheckBox)sender;
            cBox.Checked = true;
            if (cBox == checkBox6 || cBox == checkBox7)
                CheckBackColor(cBox);
            else
                CheckForeColor(cBox);
            bInCheck = false;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            graDraw.SetPenSize(int.Parse(textBox1.Text));
        }

        private void button4_Click(object sender, EventArgs e)
        {
            graDraw.SetAlpha(int.Parse(textBox2.Text));
        }

        private void button5_Click(object sender, EventArgs e)
        {
            graDraw.GetMask("auto");
        }

        private void button6_Click(object sender, EventArgs e)
        {
            graDraw.ClearGraphic();
        }
    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值