天天看点

根据VM案例仿写上位机的记录和简单参考

我前面写了2篇关于VM案例的一个讲解,和关于VM案例的一个回调函数模块仿写的方法。现在我展示的是我仿写的VM案例所得到的上位机的记录,主要是对我学习的一个记录和一个上位机的书写的参考吧。

先上图进行展示

根据VM案例仿写上位机的记录和简单参考

由于代码量很多,所以我先对我主要的模块进行一个讲解先。

首先我保留的控件有:开启VM,关闭VM,单步执行,加载方案,进度条,图像显示,清空消息,关闭方案,还有一个新增的数据表显示。

我在上位机中,将加载句柄,注册回调函数,开启VM集成到开启VM的按钮中,我在对路径的选取上都是使用绝对路径进行选取,所以在路径上需要更改一下。

然后数据表是可以用来显示我当前运行的job号和我需要输出X坐标Y坐标。

还有部分TCP的一个通讯执行程序。

具体直接上代码,大家可以作为参考。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using iMVS_6000PlatformSDKCS;
using FrontedUI;
using log4net;
using System.Diagnostics;
using HPSocketCS;
using static System.Net.Mime.MediaTypeNames;
using System.Text;
using System.Net.Sockets;

namespace iMVS_6000PlatformSDKDemo_CS
{
    public partial class PlatformSDKForm : Form
    {
        private static ILog log = log4net.LogManager.GetLogger(typeof(PlatformSDKForm));
        // 全局变量定义
        public IntPtr m_handle            = IntPtr.Zero;                                   // SDK4Server句柄
        List<string>  arrayParamVal       = new List<string>();                            // 参数列表对应值
        private delegateOutputCallBack PlatformInfoCallBack;                               // 回调函数委托  
        public uint   m_nContinStatus     = 9999;                                          // 连续运行状态值
        public uint   m_nStopStatus       = 9999;                                          // 停止运行状态值
        public uint   m_nWorkStatus       = 9999;                                          // 流程工作状态值
        public uint   m_nModuHbID         = 9999;                                          // 模块心跳异常状态值
        public uint   m_nServerHbStatus   = 9999;                                          // 服务心跳异常状态值
        public uint   m_nClientHbStatus   = 9999;                                          // 界面心跳异常状态值
        public uint   m_nDongleStatus     = 9999;                                          // 加密狗异常状态值
        public uint   m_nShowCallbackFlag = 0;                                             // 显示回调内容标志位
        public uint   m_nFrontedFlag      = 0;                                             // 嵌入前端运行界面标志位
        public int    m_nShowProcessID    = 10000;                                             // 显示用流程ID
        public uint   m_nProgressFlag     = 0;                                             // 显示加载或保存进度标志位

        public bool   m_isBegin;    //流程开始标记

        public enum ParamTypeEnum
        {
            IntType = 1,
            FloatType,
            StringType,
            ImageType,
            ChunkType
        }

        //圆
        int i = 0;
        float radius = float.NaN;
        float centerx = float.NaN;
        float centery = float.NaN;

        //图像
        ImageData imageData = new ImageData();
        byte[] imagebytes;

        //轮廓点
        float[] EdgePointX;
        float[] EdgePointY;


        //匹配框
        float[] MatchBoxCenterX;
        float[] MatchBoxCenterY;
        float[] MatchBoxWidth;
        float[] MatchBoxHeight;
        float[] MatchBoxAngle;

        //匹配点
        float[] MatchPointX;
        float[] MatchPointY;

        //匹配轮廓信息
        ImvsSdkPFDefine.IMVS_PATMATCH_POINT_INFO[] outLinePointInfo;

        public PictureBox curPictureBox { get; set; }

        public PlatformSDKForm()
        {
            InitializeComponent();
            curPictureBox = pictureBoxImg;
        }
        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private void PlatformSDKForm_Load(object sender, EventArgs e)
        {
            /*
            // 1.先杀进程 避免后台残留VM 导致启动失败
            Process[] process;//创建一个PROCESS类数组
            process = Process.GetProcesses();//获取当前任务管理器所有运行中程序
            foreach (Process proces in process)//遍历
            {
                if (proces.ProcessName.Contains("VisionMaster"))
                {
                    proces.Kill();
                }
            }*/
            // 5.初始化TCP通信设置,注意:上位机TCP通讯要在方案加载初始化
            // HP Server 注册事件
            TcpServer hpServer = new TcpServer();
            hpServer.OnAccept += HpServer_OnAccept; //连接事件
            hpServer.OnClose += HpServer_OnClose;   //断开连接事件
            // 接收数据
            hpServer.OnReceive += HpServer_OnReceive;
            // 发送数据
            hpServer.OnSend += HpServer_OnSend;
            // hpServer.OnPrepareListen += HpServer_OnPrepareListen; //PrepareListen
            // 设置服务端IP
            hpServer.IpAddress = "127.0.0.1";
            // 设置端口
            hpServer.Port = Convert.ToUInt16(8000);
            hpServer.SendPolicy = SendPolicy.Direct;
            hpServer.Start();
            string strMsg = "服务端已开启并监听.";
            listBoxMsg.Items.Add(strMsg);
            listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;


            strMsg = "服务端监听Socket为{0}:{1}.";
            listBoxMsg.Items.Add(strMsg);
            listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
            string ipListen = "";
            ushort portListen = 0;
            hpServer.GetListenAddress(ref ipListen, ref portListen);
            

            // 进度条设置
            progressBarSaveAndLoad.Value   = 0;
            progressBarSaveAndLoad.Maximum = 100;
           
            // 消除ListBox在回调中使用产生警告
            ListBox.CheckForIllegalCrossThreadCalls = false;
        }
        //接收数据
        public HandleResult HpServer_OnReceive(IntPtr connId, byte[] data)
        {
            string test;
            try
            {
                test = Encoding.Default.GetString(data);
                string strMsg_01 = "服务器接受数据: " + test;
                listBoxMsg.Items.Add(strMsg_01);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                if (test == "abcde")
                {
                    User();
                    test = "";
                }
                return HandleResult.Ok;
            }
            catch (Exception)
            {
                return HandleResult.Ignore;
            }
        }
        public void User()
        {
            string strMsg = null;
            int iRet = ImvsSdkPFDefine.IMVS_EC_UNKNOWN;
            if (IntPtr.Zero == m_handle)
            {
                MessageBoxButtons msgType = MessageBoxButtons.OK;
                DialogResult diagMsg = MessageBox.Show("句柄异常, 请重启软件!", "提示", msgType);
                if (diagMsg == DialogResult.OK)
                {
                    return;
                }
            }

            iRet = ImvsPlatformSDK_API.IMVS_PF_ExecuteOnce_CS(m_handle, null);
            if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
            {
                strMsg = "tcp控制VM执行一次失败. Error Code: " + Convert.ToString(iRet, 16);
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                return;
            }
            strMsg = "tcp控制VM执行一次成功";
            listBoxMsg.Items.Add(strMsg);
            listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
            i++;
            string[] str = new string[] { i.ToString(), centerx.ToString(), centery.ToString(), DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss") };
            dataGridView1.Rows.Add(str);
            
        }
        public HandleResult HpServer_OnAccept(IntPtr connId, IntPtr pClient)
        {
       
            return HandleResult.Ok;
        }
        public HandleResult HpServer_OnClose(IntPtr connId, SocketOperation enOperation, int errorCode)
        {
            return HandleResult.Ok;
        }
        public HandleResult HpServer_OnSend(IntPtr connId, byte[] bytes)
        {            
            try
            {
                client.Send(BitConverter.GetBytes(centerx));
                client.Send(BitConverter.GetBytes(centery));
                return HandleResult.Ok;
            }
            catch (Exception)
            {
                return HandleResult.Ignore;
            }
        }
        /****************************************************************************
         * @fn           退出程序
         ****************************************************************************/
        private void PlatformSDKForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            int nRet = ImvsSdkPFDefine.IMVS_EC_UNKNOWN;
            new Thread(new ThreadStart(delegate              // 开辟线程关闭, 防止主线程连续运行时阻塞
            {
                if (IntPtr.Zero != m_handle)
                {
                    nRet = ImvsPlatformSDK_API.IMVS_PF_CloseVisionMaster_CS(m_handle);
                    Thread.Sleep(100);
                }
                if (IntPtr.Zero != m_handle)
                {
                    nRet = ImvsPlatformSDK_API.IMVS_PF_DestroyHandle_CS(m_handle);
                    m_handle = IntPtr.Zero;
                }

                e.Cancel = false;
                Environment.Exit(0);
            })) { IsBackground = true }.Start();

            e.Cancel = true;
        }

        /****************************************************************************
         * @fn           获取字符串中的数据
         ****************************************************************************/
        public static uint GetNumberUint(string strInput)
        {
            uint nRes = 0;
            if (strInput != null && strInput != string.Empty)
            {
                string strNum = strInput;
                int nIndex = strInput.IndexOf("(");
                if (nIndex > 0)
                {
                    strNum = strInput.Substring(0, nIndex);
                }

                // 正则表达式剔除非数字字符(不包含小数点.)
                strNum = Regex.Replace(strNum, @"[^\d.\d]", "");

                // 如果是数字,则转换为decimal类型
                if (Regex.IsMatch(strNum, @"^[+-]?\d*[.]?\d*$"))
                {
                    nRes = uint.Parse(strNum);
                }
            }
            return nRes;
        }

        /****************************************************************************
         * @fn           回调结果数据
         ****************************************************************************/
        public void delegateOutputCallBackFunc(IntPtr pInputStruct, IntPtr pUser)
        {
            //回调信息转换
            ImvsSdkPFDefine.IMVS_PF_OUTPUT_PLATFORM_INFO struInfo = (ImvsSdkPFDefine.IMVS_PF_OUTPUT_PLATFORM_INFO)Marshal.PtrToStructure(pInputStruct, typeof(ImvsSdkPFDefine.IMVS_PF_OUTPUT_PLATFORM_INFO));
            switch (struInfo.nInfoType)
            {

                // 回调模块结果信息
                case (uint)ImvsSdkPFDefine.IMVS_CTRLC_OUTPUT_PlATFORM_INFO_TYPE.IMVS_ENUM_CTRLC_OUTPUT_PLATFORM_INFO_MODULE_RESULT:
                    {
                        // ImvsSdkPFDefine.IMVS_PF_MODULE_RESULT_INFO_LIST resultInfo = (ImvsSdkPFDefine.IMVS_PF_MODULE_RESULT_INFO_LIST)Marshal.PtrToStructure(struInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_MODULE_RESULT_INFO_LIST));
                        // if (m_nShowProcessID == resultInfo.nProcessID)
                        // {
                        //     UpdateDataResutExOutput(resultInfo);
                        // }

                        ImvsSdkPFDefine.IMVS_PF_MODU_RES_INFO resModuInfo = (ImvsSdkPFDefine.IMVS_PF_MODU_RES_INFO)Marshal.PtrToStructure(struInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_MODU_RES_INFO));
                        if ((m_nShowProcessID == resModuInfo.nProcessID) && (0 == m_nProgressFlag))
                        {
                            UpdateDataModuResutOutput(resModuInfo);
                        }

                        break;
                    }

                // 回调流程工作状态信息
                case (uint)ImvsSdkPFDefine.IMVS_CTRLC_OUTPUT_PlATFORM_INFO_TYPE.IMVS_ENUM_CTRLC_OUTPUT_PLATFORM_INFO_WORK_STATE:
                    {
                        ImvsSdkPFDefine.IMVS_PF_MODULE_WORK_STAUS stWorkStatus = (ImvsSdkPFDefine.IMVS_PF_MODULE_WORK_STAUS)Marshal.PtrToStructure(struInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_MODULE_WORK_STAUS));
                        m_nWorkStatus = stWorkStatus.nWorkStatus;

                        if ((m_nShowProcessID == stWorkStatus.nProcessID) && (0 == m_nProgressFlag))
                        {
                            SetTitleBarStatus(stWorkStatus);
                            
                        }

                        break;
                    }

                default:
                    {
                        break;
                    }
            }

        }

        /****************************************************************************
         * @fn           接收回调结果数据
         ****************************************************************************/
        internal void UpdateDataResutExOutput(ImvsSdkPFDefine.IMVS_PF_MODULE_RESULT_INFO_LIST struResultInfo)
        {
            if (curPictureBox != null)
            {
                for (int i = 0; i < struResultInfo.nResultNum; i++)
                {
                    switch (struResultInfo.pstModuResInfo[i].nParamType)
                    {
                        case (int)ParamTypeEnum.IntType:
                            switch (struResultInfo.pstModuResInfo[i].strParamName)
                            {
                                case "width":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        imageData.Width = struResultInfo.pstModuResInfo[i].pIntValue[0];
                                    }
                                    break;
                                case "height":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        imageData.Height = struResultInfo.pstModuResInfo[i].pIntValue[0];
                                    }
                                    break;
                            }
                            break;
                        case (int)ParamTypeEnum.FloatType:
                            switch (struResultInfo.pstModuResInfo[i].strParamName)
                            {
                                case "radius":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        radius = struResultInfo.pstModuResInfo[i].pFloatValue[0];
                                    }
                                    break;
                                case "centerx":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        centerx = struResultInfo.pstModuResInfo[i].pFloatValue[0];
                                    }
                                    break;
                                case "centery":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        centery = struResultInfo.pstModuResInfo[i].pFloatValue[0];
                                    }
                                    break;
                                case "MatchOutlineX":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        EdgePointX = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, EdgePointX, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchOutlineY":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        EdgePointY = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, EdgePointY, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchBoxCenterX":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchBoxCenterX = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchBoxCenterX, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchBoxCenterY":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchBoxCenterY = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchBoxCenterY, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchBoxWidth":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchBoxWidth = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchBoxWidth, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchBoxHeight":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchBoxHeight = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchBoxHeight, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchBoxAngle":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchBoxAngle = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchBoxAngle, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchPointX":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchPointX = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchPointX, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                                case "MatchPointY":
                                    if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                    {
                                        MatchPointY = new float[struResultInfo.pstModuResInfo[i].nValueNum];
                                        Array.Copy(struResultInfo.pstModuResInfo[i].pFloatValue, MatchPointY, struResultInfo.pstModuResInfo[i].nValueNum);
                                    }
                                    break;
                            }
                            break;
                        case (int)ParamTypeEnum.StringType:
                            break;
                        case (int)ParamTypeEnum.ImageType:
                            if (0 == String.Compare(struResultInfo.pstModuResInfo[i].strParamName, "image"))
                            {
                                if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                {
                                    imagebytes = IntPtr2Bytes(struResultInfo.pstModuResInfo[i].pstImageValue[0].pData, (int)struResultInfo.pstModuResInfo[i].pstImageValue[0].nLen);
                                }
                            }
                            break;
                        case (int)ParamTypeEnum.ChunkType:
                            if (0 == String.Compare(struResultInfo.pstModuResInfo[i].strParamName, "MatchOutline"))
                            {
                                if (struResultInfo.pstModuResInfo[i].nValueNum > 0)
                                {
                                    // 匹配轮廓信息
                                    byte[] pointsBytes = IntPtr2Bytes(struResultInfo.pstModuResInfo[i].pstChunkValue[0].pData, (int)struResultInfo.pstModuResInfo[i].pstChunkValue[0].nLen);
                                    const int singlePointInfoLen = 16;
                                    int pointNum = pointsBytes.Length / singlePointInfoLen;
                                    IntPtr structPtr = Marshal.AllocHGlobal(singlePointInfoLen);
                                    int curPointIndex = 0;
                                    for (int j = 0; j < pointsBytes.Length; j += singlePointInfoLen)
                                    {
                                        Marshal.Copy(pointsBytes, j, structPtr, 16);
                                        outLinePointInfo[curPointIndex] = (ImvsSdkPFDefine.IMVS_PATMATCH_POINT_INFO)Marshal.PtrToStructure(structPtr, typeof(ImvsSdkPFDefine.IMVS_PATMATCH_POINT_INFO));
                                        curPointIndex++;
                                    }
                                    Marshal.FreeHGlobal(structPtr);
                                }
                            }
                            break;

                        default: break;
                    }
                }
            }
        }

        /****************************************************************************
         * @fn           接收回调结果数据(模块结果)
         ****************************************************************************/
        internal void UpdateDataModuResutOutput(ImvsSdkPFDefine.IMVS_PF_MODU_RES_INFO struResultInfo)
        {
            if (curPictureBox != null)
            {
                if (null == struResultInfo.pData)
                {
                    return;
                }

                switch (struResultInfo.strModuleName)
                {
                    case ImvsSdkPFDefine.MODU_NAME_LOCALIMAGEVIEW:
                        ImvsSdkPFDefine.IMVS_PF_LOCALIMAGEVIEW_MODU_INFO stLocalImgInfo = (ImvsSdkPFDefine.IMVS_PF_LOCALIMAGEVIEW_MODU_INFO)Marshal.PtrToStructure(struResultInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_LOCALIMAGEVIEW_MODU_INFO));
                        imageData.Width = stLocalImgInfo.stImgInfo.iWidth;
                        imageData.Height = stLocalImgInfo.stImgInfo.iHeight;
                        imagebytes = IntPtr2Bytes(stLocalImgInfo.stImgInfo.pImgData, stLocalImgInfo.stImgInfo.iImgDataLen);
                        break;
                    case ImvsSdkPFDefine.MODU_NAME_CAMERAMODULE:
                        ImvsSdkPFDefine.IMVS_PF_CAMERAMODULE_INFO stCameraImgInfo = (ImvsSdkPFDefine.IMVS_PF_CAMERAMODULE_INFO)Marshal.PtrToStructure(struResultInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_CAMERAMODULE_INFO));
                        imageData.Width = stCameraImgInfo.stImgInfo.iWidth;
                        imageData.Height = stCameraImgInfo.stImgInfo.iHeight;
                        imagebytes = IntPtr2Bytes(stCameraImgInfo.stImgInfo.pImgData, stCameraImgInfo.stImgInfo.iImgDataLen);
                        break;
                    case ImvsSdkPFDefine.MODU_NAME_CIRCLEFINDMODU:
                        ImvsSdkPFDefine.IMVS_PF_CIRCLEFIND_MODU_INFO stCirFindInfo = (ImvsSdkPFDefine.IMVS_PF_CIRCLEFIND_MODU_INFO)Marshal.PtrToStructure(struResultInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_CIRCLEFIND_MODU_INFO));
                        radius = stCirFindInfo.fRadius;
                        centerx = stCirFindInfo.stCirPt.fPtX;
                        centery = stCirFindInfo.stCirPt.fPtY;
                        break;
                    case ImvsSdkPFDefine.MODU_NAME_FASTFEATUREMATCHMODU:
                        ImvsSdkPFDefine.IMVS_PF_FASTFEATUREMATCH_MODU_INFO stFeatMatchInfo = (ImvsSdkPFDefine.IMVS_PF_FASTFEATUREMATCH_MODU_INFO)Marshal.PtrToStructure(struResultInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_FASTFEATUREMATCH_MODU_INFO));

                        if (stFeatMatchInfo.iMatchNum > 0)
                        {
                            EdgePointX = new float[stFeatMatchInfo.iMatchNum];
                            EdgePointY = new float[stFeatMatchInfo.iMatchNum];
                            MatchBoxCenterX = new float[stFeatMatchInfo.iMatchNum];
                            MatchBoxCenterY = new float[stFeatMatchInfo.iMatchNum];
                            MatchBoxWidth = new float[stFeatMatchInfo.iMatchNum];
                            MatchBoxHeight = new float[stFeatMatchInfo.iMatchNum];
                            MatchBoxAngle = new float[stFeatMatchInfo.iMatchNum];
                            MatchPointX = new float[stFeatMatchInfo.iMatchNum];
                            MatchPointY = new float[stFeatMatchInfo.iMatchNum];

                            for (int i = 0; i < stFeatMatchInfo.iMatchNum; i++)
                            {
                                EdgePointX[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchPt.stMatchPt.fPtX;
                                EdgePointY[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchPt.stMatchPt.fPtY;
                                MatchBoxCenterX[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtX;
                                MatchBoxCenterY[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtY;
                                MatchBoxWidth[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.fWidth;
                                MatchBoxHeight[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.fHeight;
                                MatchBoxAngle[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.fAngle;
                                MatchPointX[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtX;
                                MatchPointY[i] = stFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtY;
                            }
                        }       

                        if (stFeatMatchInfo.stMatchConInfo.iPtNum > 0)
                        {
                            outLinePointInfo = new ImvsSdkPFDefine.IMVS_PATMATCH_POINT_INFO[stFeatMatchInfo.stMatchConInfo.iPtNum];
                            outLinePointInfo = stFeatMatchInfo.stMatchConInfo.pstPatMatchPt;
                        }                       
                        break;
                    case ImvsSdkPFDefine.MODU_NAME_HPFEATUREMATCHMODU:
                        ImvsSdkPFDefine.IMVS_PF_HPFEATUREMATCH_MODU_INFO stHpFeatMatchInfo = (ImvsSdkPFDefine.IMVS_PF_HPFEATUREMATCH_MODU_INFO)Marshal.PtrToStructure(struResultInfo.pData, typeof(ImvsSdkPFDefine.IMVS_PF_HPFEATUREMATCH_MODU_INFO));
                        if (stHpFeatMatchInfo.iMatchNum > 0)
                        {
                            EdgePointX = new float[stHpFeatMatchInfo.iMatchNum];
                            EdgePointY = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchBoxCenterX = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchBoxCenterY = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchBoxWidth = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchBoxHeight = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchBoxAngle = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchPointX = new float[stHpFeatMatchInfo.iMatchNum];
                            MatchPointY = new float[stHpFeatMatchInfo.iMatchNum];
                            for (int i = 0; i < stHpFeatMatchInfo.iMatchNum; i++)
                            {
                                EdgePointX[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchPt.stMatchPt.fPtX;
                                EdgePointY[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchPt.stMatchPt.fPtY;
                                MatchBoxCenterX[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtX;
                                MatchBoxCenterY[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtY;
                                MatchBoxWidth[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.fWidth;
                                MatchBoxHeight[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.fHeight;
                                MatchBoxAngle[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.fAngle;
                                MatchPointX[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtX;
                                MatchPointY[i] = stHpFeatMatchInfo.pstMatchBaseInfo[i].stMatchBox.stCenterPt.fPtY;
                            }
                        }

                        if (stHpFeatMatchInfo.stMatchConInfo.iPtNum > 0)
                        {
                            outLinePointInfo = new ImvsSdkPFDefine.IMVS_PATMATCH_POINT_INFO[stHpFeatMatchInfo.stMatchConInfo.iPtNum];
                            outLinePointInfo = stHpFeatMatchInfo.stMatchConInfo.pstPatMatchPt;
                        }                        
                        break;

                    default: break;
                }
            }
        }

        /****************************************************************************
         * @fn           绘制结果图像及特征
         ****************************************************************************/
        internal void SetTitleBarStatus(iMVS_6000PlatformSDKCS.ImvsSdkPFDefine.IMVS_PF_MODULE_WORK_STAUS statusInfo)
        {
            //流程开始标志 1:开始 0:结束 
            if (0 != statusInfo.nWorkStatus)
            {
                m_isBegin = true;
                InitResultData();
            }
            else if (m_isBegin)
            {
                m_isBegin = false;

                //图像
                if (imageData.Width != 0 && imageData.Height != 0 && imagebytes != null)
                {
                    uint ImageLenth = (uint)(imageData.Width * imageData.Height);
                    if (ImageLenth != imagebytes.Length)
                    {
                        return;
                    }
                    imageData.ImageBuffer = imagebytes;

                    //获取图像数据
                    if (imageData.ImageBuffer != null)
                    {
                        var bmp = imageData.ImageDataToBitmap().GetArgb32BitMap();
                        using (var g = bmp.CreateGraphic())
                        {
                            //画圆
                            if (!float.IsNaN(radius) && !float.IsNaN(centerx) && !float.IsNaN(centery))
                            {
                                g.DrawCircle(Color.GreenYellow, 3, new PointF(centerx, centery), radius);
                                g.DrawPoint(Color.GreenYellow, new PointF(centerx, centery));
                            }

                            //画轮廓点
                            if (EdgePointX != null && EdgePointY != null && EdgePointX.Length == EdgePointY.Length)
                            {
                                for (int i = 0; i < EdgePointX.Length; i++)
                                {
                                    g.DrawPoint(Color.GreenYellow, new PointF(EdgePointX[i], EdgePointY[i]));
                                }
                            }

                            //画匹配框
                            if (MatchBoxCenterX != null && MatchBoxCenterY != null && MatchBoxWidth != null && MatchBoxHeight != null && MatchBoxAngle != null &&
                                MatchBoxCenterX.Length == MatchBoxCenterY.Length && MatchBoxCenterX.Length == MatchBoxWidth.Length && MatchBoxCenterX.Length == MatchBoxHeight.Length && MatchBoxCenterX.Length == MatchBoxAngle.Length)
                            {
                                for (int i = 0; i < MatchBoxCenterX.Length; i++)
                                {
                                    g.DrawRect(Color.GreenYellow, 3, new PointF(MatchBoxCenterX[i], MatchBoxCenterY[i]), MatchBoxWidth[i], MatchBoxHeight[i], MatchBoxAngle[i]);
                                    g.DrawPoint(Color.GreenYellow, new PointF(MatchBoxCenterX[i], MatchBoxCenterY[i]));
                                }
                            }

                            //画匹配点
                            if (MatchPointX != null && MatchPointY != null && MatchPointX.Length == MatchPointY.Length)
                            {
                                for (int i = 0; i < MatchPointX.Length; i++)
                                {
                                    g.DrawPoint(Color.Red, new PointF(MatchPointX[i], MatchPointY[i]));
                                }
                            }

                            //画匹配轮廓点
                            if (outLinePointInfo != null)
                            {
                                for (int k = 0; k < outLinePointInfo.Length; k++)
                                {
                                    g.DrawPoint(Color.GreenYellow, new PointF(outLinePointInfo[k].fMatchOutlineX, outLinePointInfo[k].fMatchOutlineY));
                                }
                            }

                            curPictureBox.Invoke(new Action(() =>
                            {
                                curPictureBox.Image = bmp;
                            }));
                        }
                    }
                }
            }
        }

        /****************************************************************************
       * @fn           初始化结果数据
       ****************************************************************************/
        private void InitResultData()
        {
            //图像
            imageData = new ImageData();
            imagebytes = null;

            //轮廓点
            EdgePointX = null;
            EdgePointY = null;

            MatchBoxCenterX = null;
            MatchBoxCenterY = null;

            //匹配框
            MatchBoxCenterX = null;
            MatchBoxCenterY = null;
            MatchBoxWidth = null;
            MatchBoxHeight = null;
            MatchBoxAngle = null;

            //匹配点
            MatchPointX = null;
            MatchPointY = null;

            //匹配轮廓信息
            outLinePointInfo = null;
        }

        /****************************************************************************
         * @fn           开启算法平台
         ****************************************************************************/
        private void buttonOpenVM_Click(object sender, EventArgs e)
        {


            string strMsg = null;

            // 创建句柄
            if (IntPtr.Zero != m_handle)
            {
                ImvsPlatformSDK_API.IMVS_PF_DestroyHandle_CS(m_handle);
                m_handle = IntPtr.Zero;
            }
            string strServerPath = "D:\\VM\\VisionMaster3.1.0\\Applications\\Server\\VisionMasterServer.exe";
            if (IntPtr.Zero == m_handle)
            {
                m_handle = ImvsPlatformSDK_API.IMVS_PF_CreateHandle_CS(strServerPath);
                if (m_handle == IntPtr.Zero)
                {
                    strMsg = "句柄创建错误.";
                    listBoxMsg.Items.Add(strMsg);
                    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                    return;
                }

                strMsg = "句柄创建成功.";
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
            }

            // 注册回调
            IntPtr pUser = new IntPtr();
            pUser = this.Handle;
            PlatformInfoCallBack = new delegateOutputCallBack(delegateOutputCallBackFunc);
            int iRet = ImvsPlatformSDK_API.IMVS_PF_RegisterResultCallBack_V30_CS(m_handle, PlatformInfoCallBack, pUser);
            if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
            {
                strMsg = "注册回调失败";
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                return;
            }

            uint   nWaitTime = 30000;
            strMsg    = null;
            if (IntPtr.Zero == m_handle)
            {
                MessageBoxButtons msgType = MessageBoxButtons.OK;
                DialogResult diagMsg = MessageBox.Show("句柄异常, 请重启软件!", "提示", msgType);
                if (diagMsg == DialogResult.OK)
                {
                    return;
                }
            }

            string strPlatformPath = "D:\\VM\\VisionMaster3.1.0\\Applications\\VisionMaster.exe";
            iRet = ImvsPlatformSDK_API.IMVS_PF_StartVisionMaster_CS(m_handle, strPlatformPath, nWaitTime);
            if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
            {
                strMsg = "开启VM失败. Error Code: " + Convert.ToString(iRet, 16);
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                return;
            }
            Thread.Sleep(2000);
            strMsg = "VM开启成功.";
            listBoxMsg.Items.Add(strMsg);
            listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
        }

        /****************************************************************************
         * @fn           关闭算法平台
         ****************************************************************************/
        private void buttonCloseVM_Click(object sender, EventArgs e)
        {
            new Thread(new ThreadStart(delegate              // 开辟线程关闭, 防止主线程连续运行时阻塞
            {
                string strMsg = null;
                if (IntPtr.Zero == m_handle)
                {
                    MessageBoxButtons msgType = MessageBoxButtons.OK;
                    DialogResult diagMsg = MessageBox.Show("句柄异常, 请重启软件!", "提示", msgType);
                    if (diagMsg == DialogResult.OK)
                    {
                        return;
                    }
                }

                int iRet = ImvsSdkPFDefine.IMVS_EC_UNKNOWN;
                if (1 == m_nFrontedFlag)
                {
                    iRet = ImvsPlatformSDK_API.IMVS_PF_UnAttachFrontedWnd_CS(m_handle, pictureBoxImg.Handle);
                    if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
                    {
                        strMsg = "IMVS_PF_UnAttachFrontedWnd_CS Failed. Error Code: " + Convert.ToString(iRet, 16);
                        listBoxMsg.Items.Add(strMsg);
                        listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                    }

                    m_nFrontedFlag = 0;
                }

                iRet = ImvsPlatformSDK_API.IMVS_PF_CloseVisionMaster_CS(m_handle);
                if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
                {
                    strMsg = "IMVS_PF_CloseVisionMaster_CS Failed. Error Code: " + Convert.ToString(iRet, 16);
                    listBoxMsg.Items.Add(strMsg);
                    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                    return;
                }
                strMsg = "IMVS_PF_CloseVisionMaster_CS Success.";
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;

                // 清空图像
                curPictureBox.Image = null;
                curPictureBox.Refresh();
            })) { IsBackground = true }.Start();
        }

        /****************************************************************************
         * @fn           执行一次
         ****************************************************************************/
        private void buttonExecuteOnce_Click(object sender, EventArgs e)
        {
            string strMsg = null;
            int iRet = ImvsSdkPFDefine.IMVS_EC_UNKNOWN;
            if (IntPtr.Zero == m_handle)
            {
                MessageBoxButtons msgType = MessageBoxButtons.OK;
                DialogResult diagMsg = MessageBox.Show("句柄异常, 请重启软件!", "提示", msgType);
                if (diagMsg == DialogResult.OK)
                {
                    return;
                }
            }

                iRet = ImvsPlatformSDK_API.IMVS_PF_ExecuteOnce_CS(m_handle, null);
                if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
                {
                    strMsg = "VM执行一次失败. Error Code: " + Convert.ToString(iRet, 16);
                    listBoxMsg.Items.Add(strMsg);
                    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                    return;
                }

                strMsg = "VM执行一次成功";
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
            i++;
            string[] str = new string[] { i.ToString(), centerx.ToString(), centery.ToString(), DateTime.Now.ToString("yyyy:MM:dd:HH:mm:ss") };
            dataGridView1.Rows.Add(str);
        }

        /****************************************************************************
         * @fn           加载方案
         ****************************************************************************/
        private void buttonLoadSolution_Click(object sender, EventArgs e)
        {
            string strMsg = null;
            progressBarSaveAndLoad.Value = 0;
            uint nProcess = 0;
            labelProgress.Text = nProcess.ToString();
            labelProgress.Refresh();

            int iRet = ImvsSdkPFDefine.IMVS_EC_UNKNOWN;
            if (IntPtr.Zero == m_handle)
            {
                MessageBoxButtons msgType = MessageBoxButtons.OK;
                DialogResult diagMsg = MessageBox.Show("句柄异常, 请重启软件!", "提示", msgType);
                if (diagMsg == DialogResult.OK)
                {
                    return;
                }
            }

            if (1 == m_nFrontedFlag)
            {
                iRet = ImvsPlatformSDK_API.IMVS_PF_UnAttachFrontedWnd_CS(m_handle, pictureBoxImg.Handle);
                if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
                {
                    strMsg = "IMVS_PF_UnAttachFrontedWnd_CS Failed. Error Code: " + Convert.ToString(iRet, 16);
                    listBoxMsg.Items.Add(strMsg);
                    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                }

                m_nFrontedFlag = 0;
            }

            string strSolutionPath = "D:\\VMxiangmu\\test09\\iMVS-6000PlatformSDKDemo_CS\\zuoye.sol";
            iRet = ImvsPlatformSDK_API.IMVS_PF_LoadSolution_CS(m_handle, strSolutionPath, "");
            if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
            {
                strMsg = "VM方案加载失败. Error Code: " + Convert.ToString(iRet, 16);
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                return;
            }
            strMsg = "VM方案加载成功";
            listBoxMsg.Items.Add(strMsg);
            listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;

            DateTime dtStart = DateTime.Now;
            uint nProgress = 0;
            m_nProgressFlag = 1;    // 显示加载方案进度标志位置位
            for (; nProgress < 100;)
            {
                iRet = ImvsPlatformSDK_API.IMVS_PF_GetLoadProgress_CS(m_handle, ref nProgress);

                labelProgress.Text = nProgress.ToString();
                labelProgress.Refresh();
                progressBarSaveAndLoad.Value = Convert.ToInt32(nProgress);

                if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
                {
                    strMsg = "获取VM加载流程标识失败. Error Code: " + Convert.ToString(iRet, 16);
                    listBoxMsg.Items.Add(strMsg);
                    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                    return;
                }

                Thread.Sleep(300);

                TimeSpan spanNow = new TimeSpan();
                spanNow = DateTime.Now - dtStart;
                if (spanNow.Seconds > 50)    // 50s后退出循环, 防止死循环
                {
                    break;
                }
            }
            m_nProgressFlag = 0;    // 显示加载方案进度标志位复位
        }

        /****************************************************************************
         * @fn           关闭方案
         ****************************************************************************/
        private void buttonCloseSolution_Click(object sender, EventArgs e)
        {
            string strMsg = null;
            int    iRet   = ImvsSdkPFDefine.IMVS_EC_UNKNOWN;
            if (IntPtr.Zero == m_handle)
            {
                MessageBoxButtons msgType = MessageBoxButtons.OK;
                DialogResult diagMsg = MessageBox.Show("句柄异常, 请重启软件!", "提示", msgType);
                if (diagMsg == DialogResult.OK)
                {
                    return;
                }
            }

            if (1 == m_nFrontedFlag)
            {
                iRet = ImvsPlatformSDK_API.IMVS_PF_UnAttachFrontedWnd_CS(m_handle, pictureBoxImg.Handle);
                if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
                {
                    strMsg = "IMVS_PF_UnAttachFrontedWnd_CS Failed. Error Code: " + Convert.ToString(iRet, 16);
                    listBoxMsg.Items.Add(strMsg);
                    listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                }

                m_nFrontedFlag = 0;
            }

            iRet = ImvsPlatformSDK_API.IMVS_PF_CloseSolution_CS(m_handle);
            if (ImvsSdkPFDefine.IMVS_EC_OK != iRet)
            {
                strMsg = "IMVS_PF_CloseSolution_CS Failed. Error Code: " + Convert.ToString(iRet, 16);
                listBoxMsg.Items.Add(strMsg);
                listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
                return;
            }

            // 清空PictureBox控件中的内容
            pictureBoxImg.Image = null;
            pictureBoxImg.Refresh();

            strMsg = "IMVS_PF_CloseSolution_CS Success";
            listBoxMsg.Items.Add(strMsg);
            listBoxMsg.TopIndex = listBoxMsg.Items.Count - 1;
        }

        /****************************************************************************
         * @fn           清空消息
         ****************************************************************************/
        private void buttonDeleteMsg_Click(object sender, EventArgs e)
        {
            listBoxMsg.Items.Clear();
        }

        /****************************************************************************
         * @fn           IntPtr转Bytes
         ****************************************************************************/
        public static byte[] IntPtr2Bytes(IntPtr ptr, int size)
        {
            byte[] bytes = null;
            if ((size > 0) && (null != ptr))
            {
                bytes = new byte[size];
                Marshal.Copy(ptr, bytes, 0, size);
            }
            return bytes;
        }

        private void textBoxTimeInterval_TextChanged(object sender, EventArgs e)
        {

        }

        private void groupBoxTimeInterval_Enter(object sender, EventArgs e)
        {

        }

        private void label11_Click(object sender, EventArgs e)
        {

        }
    }
}