Newer
Older
laserPTZ_CS / insertForm / CtrlHome.cs
wangxitong on 11 Sep 42 KB first commit
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Threading;
using ImageFormatter;

namespace laserPTZ.insertForm
{
    public partial class CtrlHome : UserControl
    {
        public static CtrlHome ctrlHome = null;
        static TreeNode selectedNode = null;
        private bool m_bInitSDK = false;
        private uint iLastErr = 0;
        // 登录4个设备的userID
        public static Int32 m_lUserID1 = -1, m_lUserID2 = -1, m_lUserID3 = -1, m_lUserID4 = -1;
        // 四个框的句柄
        public static Int32 m_lRealHandle1 = -1,  m_lRealHandle2 = -1, m_lRealHandle3 = -1, m_lRealHandle4 = -1, m_lRealHandle5 = -1;
        // 四个框是否在播
        private bool isLiveShow_1 = false, isLiveShow_2 = false, isLiveShow_3 = false, isLiveShow_4 = false;
        // 四个框设备index
        public static int activeIndex_1 = -1, activeIndex_2 = -1, activeIndex_3 = -1, activeIndex_4 = -1;
        // 四个设备的rtsp
        private string rtspUrl_1 = "", rtspUrl_2 = "", rtspUrl_3 = "", rtspUrl_4 = "";

        public static string hasNVR = ConfigHelper.GetAppConfig("hasNVR");
        public static string flow = ConfigHelper.GetAppConfig("flow");

        public CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo;
        CHCNetSDK.LOGINRESULTCALLBACK LoginCallBack = null;
        public CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo;
        CHCNetSDK.REALDATACALLBACK RealData = null;
        
        public static int pictureBoxIndex = 0;
        public static int videoStartIndex = 0;
        public static int monitorLocationIndex = 0;
        public static JArray moniterArr = null;
        string monitorId = "", monitorName = ""; 
        System.Threading.Timer timer1 = null;
        public static Dictionary<string, int> userIdMap = new Dictionary<string, int>();
        
        public static int userIdNVR = -1; //NVR UserID
        public static int[] iChannelNum = new int[96]; //NVR 通道

        CHCNetSDK.NET_DVR_IPPARACFG_V40 m_struIpParaCfgV40;

        public CtrlHome(){
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            ctrlHome = this;
            if (!m_bInitSDK)
            {
                m_bInitSDK = CHCNetSDK.NET_DVR_Init();
                if (m_bInitSDK == false)
                {
                    MessageBox.Show("NET_DVR_Init error!");
                    return;
                }
                else
                {
                    CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true); //保存SDK日志 To save the SDK log
                }
            }
            chart1.Series["Series1"].XValueMember = "logTime";
            chart1.Series["Series1"].YValueMembers = "concentration";
            chart1.Series["Series1"].MarkerStyle = MarkerStyle.Circle;   //线条上的数据点标志类型  
            chart1.Series["Series1"].MarkerSize = 3;  //标志大小 
        }
        
        public void setUserIdMap()
        {
            new Thread(new ThreadStart(() =>
            {
                try
                {
                    userIdMap.Clear();
                    if (hasNVR == "1") //登录NVR
                    {
                        CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
                        userIdNVR = CHCNetSDK.NET_DVR_Login_V30(ConfigHelper.GetAppConfig("NVRIP"), int.Parse(ConfigHelper.GetAppConfig("NVRPort")), ConfigHelper.GetAppConfig("NVRUsername"), ConfigHelper.GetAppConfig("NVRPassword"), ref DeviceInfo);
                        uint dwSize = (uint)Marshal.SizeOf(m_struIpParaCfgV40);
                        IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal((Int32)dwSize);
                        Marshal.StructureToPtr(m_struIpParaCfgV40, ptrIpParaCfgV40, false);
                        uint dwReturn = 0;
                        int iGroupNo = 0; //该Demo仅获取第一组64个通道,如果设备IP通道大于64路,需要按组号0~i多次调用NET_DVR_GET_IPPARACFG_V40获取
                        if (CHCNetSDK.NET_DVR_GetDVRConfig(userIdNVR, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
                        {
                            m_struIpParaCfgV40 = (CHCNetSDK.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(CHCNetSDK.NET_DVR_IPPARACFG_V40));

                            for (int j = 0; j < moniterArr.Count; j++) // NVR的通道
                            {
                                iChannelNum[j] = -1;
                                string ip = moniterArr[j]["deviceIp"].ToString();
                                
                                for (int i = 0; i < m_struIpParaCfgV40.dwDChanNum; i++)
                                {
                                    if(ip == Encoding.UTF8.GetString(m_struIpParaCfgV40.struIPDevInfo[i].struIP.sIpV4).Replace("\0",""))
                                    {
                                        iChannelNum[j] = i + (int)m_struIpParaCfgV40.dwStartDChan;
                                        break;
                                    }
                                }

                            }
                        }
                    }

                    bool isPreview = false;
                    for (int i = 0; i < moniterArr.Count; i++) // 登录所有设备
                    {
                        JToken j = moniterArr[i];
                        if (j["deviceIp"].ToString() != "" && j["devicePort"].ToString() != "" && j["deviceUser"].ToString() != "" && j["devicePassword"].ToString() != "")
                        {
                            int userId = loginDevice(j["deviceIp"].ToString(), j["devicePort"].ToString(), j["deviceUser"].ToString(), j["devicePassword"].ToString());
                            userIdMap.Add(j["monitorPointId"].ToString(), userId);
                        }
                        if(!isPreview && (i == (moniterArr.Count-1) || i == 3))
                        {
                            isPreview = true;
                            changePage(0);
                        }
                    }
                    if (hasNVR == "0") { // 删除多余文件(不配备NVR)
                        deleteVideoFiles();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "setUserIdMap");
                }
            })).Start();
        }
        private void CtrlHome_Load(object sender, EventArgs e)
        {
            new Thread(new ThreadStart(() =>
            {
                try
                {
                    //Thread.Sleep(100);
                    if (this.IsHandleCreated)
                    {
                        this.Invoke(new EventHandler(delegate
                            {
                                int width = FormMain.formMain.panel_insert.Width;
                                int height = FormMain.formMain.panel_insert.Height;
                                this.Width = width;
                                this.Height = height;
                                panel_tree.Size = new Size((int)(0.285 * width), (int)(0.539 * height));
                                panel_tree.Location = new Point((int)(0.012 * width), 7);
                                panel_chart.Size = new Size((int)(0.285 * width), (int)(0.436 * height));
                                panel_chart.Location = new Point((int)(0.012 * width), (int)(0.547 * height));
                                panel_vedio.Size = new Size((int)(0.678 * width), (int)(0.985 * height));
                                panel_vedio.Location = new Point((int)(0.31 * width), 7);
                                panel_video1.Size = new Size((int)(0.458 * panel_vedio.Width), (int)(0.435 * panel_vedio.Height));
                                panel_video2.Size = panel_video1.Size;
                                panel_video3.Size = panel_video1.Size;
                                panel_video4.Size = panel_video1.Size;
                                panel_video1.Location = new Point((int)(0.021 * panel_vedio.Width), (int)(0.018 * Height));
                                panel_video3.Location = new Point((int)(0.021 * panel_vedio.Width), (int)(0.5 * panel_vedio.Height));
                                panel_video2.Location = new Point((int)(0.514 * panel_vedio.Width), (int)(0.018 * Height));
                                panel_video4.Location = new Point((int)(0.514 * panel_vedio.Width), (int)(0.5 * panel_vedio.Height));
                                pre_btn.Location = new Point((int)(0.43 * panel_vedio.Width), (int)(0.945 * panel_vedio.Height));
                                next_btn.Location = new Point((int)(0.54 * panel_vedio.Width), (int)(0.945 * panel_vedio.Height));
                                txt_page.Location = new Point((int)(0.464 * panel_vedio.Width), (int)(0.945 * panel_vedio.Height));
                                txt_page.Text = "第1页";
                                panel_vedio.Visible = true;
                                moniterArr = null;

                                getTreeData();
                                getChartData();

                                //自已绘制
                                this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawText;
                                this.treeView1.DrawNode += new DrawTreeNodeEventHandler(treeView1_DrawNode);
                                treeView1.ExpandAll();
                                if (selectedNode != null) drawNode();
                                treeView1.Focus();

                                panel_vedio.Visible = true;
                                panel_tree.Visible = true;
                                panel_chart.Visible = true;

                                videoStartIndex = 0;
                                setUserIdMap();
                                /*new Thread(new ThreadStart(() =>
                                {
                                    Thread.Sleep(2000);
                                    AutoResetEvent autoEvent = new AutoResetEvent(false);
                                    TimerCallback timer1Delegate = new TimerCallback(timer);
                                    timer1 = new System.Threading.Timer(timer1Delegate, autoEvent, 30000, 30000);
                                })).Start();*/
                            }));
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "CtrlHome_Load");
                }
            })).Start();
        }
        /// <summary>
        /// 初始化树节点
        /// </summary>
        public void getTreeData(){
            try
            {
                Invoke(new MethodInvoker(delegate ()
                {
                    treeView1.Nodes.Clear();
                    string query = "?keyword=" + txt_monitorName.Text.Trim();
                    string result = Http.http("http://" + ConfigHelper.GetAppConfig("server").Trim() + "/monitor/list" + query, "GET", null);
                    if (result == "")
                    {
                        label_treeResult.Text = "数据获取失败";
                        label_treeResult.ForeColor = Color.Red;
                        label_treeResult.Visible = true;
                        return;
                    }
                    JObject json = (JObject)JsonConvert.DeserializeObject(result);//或者JObject jo = JObject.Parse(jsonText);
                    if (json["data"].ToString() == "[]")
                    {
                        label_treeResult.Text = "查无数据";
                        label_treeResult.ForeColor = Color.Orange;
                        label_treeResult.Visible = true;
                        return;
                    }
                    label_treeResult.Visible = false;
                    JArray jar = JArray.Parse(json["data"].ToString());
                    for (int i = 0; i < jar.Count; i++)
                    {
                        JObject js = (JObject)JsonConvert.DeserializeObject(jar[i].ToString());
                        TreeNode Node = new TreeNode();
                        Node.Text = js["stationName"].ToString();
                        Node.Tag = js["stationId"].ToString();
                        treeView1.Nodes.Add(Node);
                        int index = Node.Index;
                        if (js["monipoiList"].ToString() != "")
                        {
                            JArray jarChild = JArray.Parse(js["monipoiList"].ToString());
                            if (moniterArr == null)
                            {
                                moniterArr = jarChild;
                            }
                            else
                            {
                                for (int k = 0; k < jarChild.Count; k++)
                                {
                                    moniterArr.Add(jarChild[k]);
                                }
                            }
                            txt_page.Text = "1/" + (moniterArr.Count / 4 + (moniterArr.Count % 4 == 0 ? 0 : 1)).ToString() + "页";
                            for (int j = 0; j < jarChild.Count; j++)
                            {
                                JObject jsChild = (JObject)JsonConvert.DeserializeObject(jarChild[j].ToString());
                                TreeNode childNode = new TreeNode();
                                childNode.Text = "     " + jsChild["monitorPointName"].ToString();
                                childNode.Tag = jsChild["monitorPointId"].ToString();
                                if (monitorId == "")
                                {
                                    monitorId = jsChild["monitorPointId"].ToString();
                                    monitorName = jsChild["monitorPointName"].ToString();
                                    treeView1.SelectedNode = childNode;
                                    selectedNode = childNode;
                                }
                                treeView1.Nodes[index].Nodes.Add(childNode);
                            }
                        }
                    }
                    treeView1.ExpandAll();
                }));
            }
            catch (Exception e)
            { }
            
        }

        public void deleteVideoFiles()
        {
            new Thread(new ThreadStart(() =>
            {
                try
                {
                    for (int i = 0; i < moniterArr.Count; i++)
                    {
                        JToken j = moniterArr[i];
                        string path = ConfigHelper.GetAppConfig("saveImagePath").Trim() + j["monitorPointName"].ToString();
                        if (System.IO.Directory.Exists(path))
                        {
                            if (System.IO.Directory.GetFiles(path).Length > 60)
                            {
                                ThoroughDeleteDirectory(path);
                            }
                        }
                    }
                }
                catch (Exception ex)  { }
            })).Start();
        }

        public static void ThoroughDeleteDirectory(string directoryPath)
        {
            foreach (var path in Directory.GetFileSystemEntries(directoryPath))
            {
                if (File.Exists(path))
                {
                    File.Delete(path);// 删除文件夹
                }
                else
                {
                    ThoroughDeleteDirectory(path);// 递归删除文件夹
                }
            }
            // 删除空文件夹
            Directory.Delete(directoryPath);
        }
        /// <summary>
        /// 初始化左下角的曲线图
        /// </summary>
        private void getChartData(){
            try
            {
                Invoke(new MethodInvoker(delegate ()
                {
                    chart1.DataSource = null;
                    
                    string timeNow = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    string timeStart = DateTime.Now.AddMinutes(-31).ToString("yyyy-MM-dd HH:mm:ss");
                    string query = "?monitorId=" + monitorId + "&" + "startTime=" + timeStart + "&" + "endTime=" + timeNow;
                    string result = Http.http("http://" + ConfigHelper.GetAppConfig("server").Trim() + "/data/hisList" + query, "GET", null);
                    if (result == "")
                    {
                        label_chartResult.Text = "服务器错误,数据获取失败";
                        label_chartResult.ForeColor = Color.OrangeRed;
                        label_chartResult.Visible = true;
                        label3.Visible = false;
                        label_chartTitle.Visible = false;
                        chart1.Visible = false;
                        return;
                    }
                    JObject json = (JObject)JsonConvert.DeserializeObject(result);//或者JObject jo = JObject.Parse(jsonText);
                    if (json["data"].ToString() == "[]")
                    {
                        label_chartResult.Text = monitorName + "无甲烷数据";
                        label_chartResult.ForeColor = Color.DimGray;
                        label_chartResult.Visible = true;
                        label_chartTitle.Visible = false;
                        label3.Visible = false;
                        chart1.Visible = false;
                        return;
                    }
                    chart1.Visible = true;
                    label_chartResult.Visible = false;
                    label_chartTitle.Visible = true;
                    label3.Visible = true;
                    label_chartTitle.Text = monitorName;

                    JArray jar = JArray.Parse(json["data"].ToString());
                    if (json["data"].ToString() != "[]")
                    {
                        DataTable tblDatas = new DataTable("Datas");

                        tblDatas.Columns.Add("ID", Type.GetType("System.Int32"));
                        tblDatas.Columns[0].AutoIncrement = true;
                        tblDatas.Columns[0].AutoIncrementSeed = 1;
                        tblDatas.Columns[0].AutoIncrementStep = 1;
                        tblDatas.Columns.Add("concentration", Type.GetType("System.String"));
                        tblDatas.Columns.Add("logTime", Type.GetType("System.String"));

                        for (int i = jar.Count -1; i >= 0; i--)
                        {
                            tblDatas.Rows.Add(new object[] { null, jar[i]["concentration"].ToString(), jar[i]["logTime"].ToString().Substring(10, 6) });
                        }

                        Series Series1 = new Series();
                        chart1.Series.Add(Series1);//加入你的chart1

                        chart1.DataSource = tblDatas;
                   
                    }
                }));
                
            }
            catch(Exception ex)
            { }
        }
        /// <summary>
        /// 相机回调函数
        /// </summary>
        public void cbLoginCallBack(int lUserID, int dwResult, IntPtr lpDeviceInfo, IntPtr pUser)
        {
            string strLoginCallBack = "登录设备,lUserID:" + lUserID + ",dwResult:" + dwResult;
            if (dwResult == 0)
            {
                uint iErrCode = CHCNetSDK.NET_DVR_GetLastError();
                strLoginCallBack = strLoginCallBack + ",错误号:" + iErrCode;
            }
            //下面代码注释掉也会崩溃
            if (InvokeRequired)
            {
                object[] paras = new object[2];
                paras[0] = strLoginCallBack;
                paras[1] = lpDeviceInfo;
                //labelLogin.BeginInvoke(new UpdateTextStatusCallback(UpdateClientList), paras);
            }
            else
            {
                //创建该控件的主线程直接更新信息列表 
                //UpdateClientList(strLoginCallBack, lpDeviceInfo);
            }
        }
        
        private int loginDevice(string ip, string port, string user, string password)
        {
            int m_lUserID = -1;
            try
            {
                struLogInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();

                //设备IP地址或者域名
                byte[] byIP = System.Text.Encoding.Default.GetBytes(ip);
                struLogInfo.sDeviceAddress = new byte[129];
                byIP.CopyTo(struLogInfo.sDeviceAddress, 0);

                //设备用户名
                byte[] byUserName = System.Text.Encoding.Default.GetBytes(user);
                struLogInfo.sUserName = new byte[64];
                byUserName.CopyTo(struLogInfo.sUserName, 0);

                //设备密码
                byte[] byPassword = System.Text.Encoding.Default.GetBytes(password);
                struLogInfo.sPassword = new byte[64];
                byPassword.CopyTo(struLogInfo.sPassword, 0);

                struLogInfo.wPort = ushort.Parse(port);//设备服务端口号

                if (LoginCallBack == null)
                {
                    LoginCallBack = new CHCNetSDK.LOGINRESULTCALLBACK(cbLoginCallBack);//注册回调函数                    
                }
                struLogInfo.cbLoginResult = LoginCallBack;
                struLogInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是 

                DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();

                //登录设备 Login the device
                m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);
                if (m_lUserID < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    string str = "NET_DVR_Login_V40 failed, error code= " + iLastErr; //登录失败,输出错误号
                    //MessageBox.Show(str);
                    return -1;
                }
                else
                {
                    //登录成功
                    //btnLogin.Text = "Logout";
                    /*if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
                    {
                        iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                        str1 = "NET_DVR_GET_IPPARACFG_V40 failed, error code= " + iLastErr; //获取IP资源配置信息失败,输出错误号
                        MessageBox.Show(str1);
                    }*/
                }
                
                return m_lUserID;
            }
            catch (Exception ex)
            { return -1; }
        }

        public int preview(IntPtr handle, int m_lUserID, int index){
            int m_lRealHandle = -1;
            CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();

            lpPreviewInfo.hPlayWnd = handle;//预览窗口
            lpPreviewInfo.lChannel = hasNVR == "0" ? Int16.Parse("1") : iChannelNum[index];//预te览的设备通道
            lpPreviewInfo.dwStreamType = uint.Parse(flow);//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推
            lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP 
            lpPreviewInfo.bBlocked = false; //0- 非阻塞取流,1- 阻塞取流
            lpPreviewInfo.dwDisplayBufNum = 1; //播放库播放缓冲区最大缓冲帧数
            lpPreviewInfo.byProtoType = 0;
            lpPreviewInfo.byPreviewMode = 0;


            if (RealData == null)
            {
                RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数
            }
            IntPtr pUser = new IntPtr();//用户数据

            //打开预览 Start live view 
            m_lRealHandle = hasNVR == "0" ? 
                CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null, pUser) :
                CHCNetSDK.NET_DVR_RealPlay_V40(userIdNVR, ref lpPreviewInfo, null, pUser);
            if (m_lRealHandle < 0)
            {
                iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                string str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号
                return -1;
            }
            return m_lRealHandle;
        }
        
        public void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser){
            if (dwBufSize > 0)
            {
                byte[] sData = new byte[dwBufSize];
                Marshal.Copy(pBuffer, sData, 0, (Int32)dwBufSize);
                string str = "实时流数据.ps";
                FileStream fs = new FileStream(str, FileMode.Create);
                int iLen = (int)dwBufSize;
                fs.Write(sData, 0, iLen);
                fs.Close();
            }
        }

        private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e){            
            if ((e.State & TreeNodeStates.Selected) != 0)
            {
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(41, 42, 73)), e.Node.Bounds);
                if (selectedNode != null)
                {
                    treeView1.CreateGraphics().FillRectangle(new SolidBrush(Color.FromArgb(119, 108, 166)), selectedNode.Bounds);
                }
                Font nodeFont = e.Node.NodeFont;
                if (nodeFont == null) nodeFont = ((TreeView)sender).Font;
                e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.White, e.Node.Bounds.X + 1, e.Node.Bounds.Y + 1);
                treeView1.SelectedNode = null;
            }
            else
            {
                e.DrawDefault = true;
            }            
        }

        private static GraphicsPath GetRoundRectangle(Rectangle rectangle, int r){
            int l = 2 * r;
            GraphicsPath gp = new GraphicsPath();// 把圆角矩形分成八段直线、弧的组合,依次加到路径中  
            gp.AddLine(new Point(rectangle.X + r, rectangle.Y), new Point(rectangle.Right - r, rectangle.Y));
            gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Y, l, l), 270F, 90F);
            gp.AddLine(new Point(rectangle.Right, rectangle.Y + r), new Point(rectangle.Right, rectangle.Bottom - r));
            gp.AddArc(new Rectangle(rectangle.Right - l, rectangle.Bottom - l, l, l), 0F, 90F);
            gp.AddLine(new Point(rectangle.Right - r, rectangle.Bottom), new Point(rectangle.X + r, rectangle.Bottom));
            gp.AddArc(new Rectangle(rectangle.X, rectangle.Bottom - l, l, l), 90F, 90F);
            gp.AddLine(new Point(rectangle.X, rectangle.Bottom - r), new Point(rectangle.X, rectangle.Y + r));
            gp.AddArc(new Rectangle(rectangle.X, rectangle.Y, l, l), 180F, 90F);
            return gp;
        }

        private void pictureBox_DoubleClick(ref bool isLiveShow, int pbIndex,  Panel panel_video, ref string rtspUrl, ref int activeIndex)
        {
            if (!isLiveShow) return;
            pictureBoxIndex = pbIndex;
            if (panel_video.BackgroundImage != Properties.Resources.小监控窗口红色)
                panel_video.BackgroundImage = Properties.Resources.小监控窗口紫色;
            FormMain.formMain.btn_home.Visible = true;
            FormMain.insertService.setToFirst(FormMain.formMain.panel_insert);
            FormMain.insertService.SetPanelControl(FormMain.formMain.panel_insert, "realTime", rtspUrl, activeIndex);
        }

        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            pictureBox_DoubleClick(ref isLiveShow_1, 1, panel_video1, ref rtspUrl_1, ref activeIndex_1);
        }

        private void pictureBox2_DoubleClick(object sender, EventArgs e)
        {
            pictureBox_DoubleClick(ref isLiveShow_2, 2, panel_video2, ref rtspUrl_2, ref activeIndex_2);
        }

        private void pictureBox3_DoubleClick(object sender, EventArgs e)
        {
            pictureBox_DoubleClick(ref isLiveShow_3, 3, panel_video3, ref rtspUrl_3, ref activeIndex_3);
        }

        private void pictureBox4_DoubleClick(object sender, EventArgs e)
        {
            pictureBox_DoubleClick(ref isLiveShow_4, 4, panel_video4, ref rtspUrl_4, ref activeIndex_4);
        }

        private void drawPanelBorder(PaintEventArgs e, Panel panel){
            ControlPaint.DrawBorder(e.Graphics, panel.ClientRectangle,
                                Color.FromArgb(139, 129, 76), 1, ButtonBorderStyle.Solid, Color.FromArgb(139, 129, 76), 1, ButtonBorderStyle.Solid,
                                Color.FromArgb(139, 129, 76), 1, ButtonBorderStyle.Solid, Color.FromArgb(139, 129, 76), 1, ButtonBorderStyle.Solid);
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e){
            if (e.Node.Parent != null) selectedNode = e.Node;
            if (selectedNode != null)
            {
                drawNode();
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)        {           
            if (e.Node.Parent != null) selectedNode = e.Node;
            if (selectedNode != null)
            {
                drawNode();
            }
        }

        private void btn_search_Click(object sender, EventArgs e)        {
            getTreeData();            
        }

        private void drawNode()     {
            Graphics g = this.treeView1.CreateGraphics();
            treeView1.Refresh();
            //g.FillRectangle(Brushes.LawnGreen, e.Node.Bounds);
            Rectangle rect = new Rectangle(selectedNode.Bounds.X - 15, selectedNode.Bounds.Y - 1, (int)(0.8 * (double)treeView1.Width), selectedNode.Bounds.Height + 1);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.FillPath(new SolidBrush(Color.FromArgb(119, 108, 166)), GetRoundRectangle(rect, 18));
            Font nodeFont = selectedNode.NodeFont;
            if (nodeFont == null) nodeFont = new Font("微软雅黑", (float)10.5);
            g.DrawString(selectedNode.Text, nodeFont, Brushes.White, selectedNode.Bounds.X - 1, selectedNode.Bounds.Y + 3);
            g.Dispose();
            treeView1.Focus();
        }

        /*protected override CreateParams CreateParams{
            get{
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000; // 用双缓冲绘制窗口的所有子控件
                return cp;
            }
        }*/

        // 双击左侧树,替换第二个窗
        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {
                treeView1.SelectedNode = e.Node;
                selectedNode = e.Node;
                for (int i = 0; i < moniterArr.Count; i++)
                {
                    JObject j = (JObject)JsonConvert.DeserializeObject(moniterArr[i].ToString());
                    string nodeName = e.Node.Text.Trim();
                    if (nodeName == j["monitorPointName"].ToString().Trim())
                    {
                        monitorId = j["monitorPointId"].ToString();
                        monitorName = j["monitorPointName"].ToString();
                        getChartData();
                        if (!userIdMap.ContainsKey(j["monitorPointId"].ToString()))
                        {
                            MessageBox.Show("请等待设备登录");
                            return;
                        }
                        if (label_title1.Text == nodeName || label_title2.Text == nodeName || label_title3.Text == nodeName || label_title4.Text == nodeName)
                        {
                            return;
                        }
                        changeVideo(i, label_title2, label_picResult2, ref m_lUserID2, ref m_lRealHandle2, ref activeIndex_2, pictureBox2, panel_video2, ref isLiveShow_2, ref rtspUrl_2); //左侧树
                        break;
                    }
                }
            }
            catch (Exception ex){}
            finally { }
        }

        public bool checkUserIdMap()
        {
            if (userIdMap.Count != moniterArr.Count)
            {
                MessageBox.Show("请等待全部设备登录", "提示");
                return false;
            }
            else return true;
        }

        public int page = 0;
        private void next_btn_Click(object sender, MouseEventArgs e)
        {
            if (moniterArr == null) return;
            if(checkUserIdMap())
            {
                if (moniterArr.Count % 4 == 0 && page >= (moniterArr.Count / 4) - 1) return;
                else if (moniterArr.Count % 4 != 0 && page >= moniterArr.Count / 4) return;
                else
                {
                    page++;
                    changePage(page);
                }
            }
        }
        
        private void pre_btn_Click(object sender, MouseEventArgs e)
        {
            if (moniterArr == null) return;
            if (checkUserIdMap())
            {
                if (page == 0) return;
                else
                {
                    page--;
                    changePage(page);
                }
            }
        }

        public void videoFail(PictureBox pictureBox, ref bool isLiveShow, Label label_picResult, string msg)
        {
            pictureBox.Invalidate();
            pictureBox.Image = null;
            isLiveShow = false;
            label_picResult.Invoke(new EventHandler(delegate
            {
                label_picResult.Text = msg;
                label_picResult.Visible = true;
            }));
        }
        
        // 切换回首页
        public void rePreviewNow()
        {
            changePage(page);
        }

        public void changeVideo( int index, Label label_title, Label label_picResult, ref Int32 m_lUserID,
            ref Int32 m_lRealHandle, ref int activeIndex, PictureBox pictureBox, Panel panel_video, ref bool isLiveShow, ref string rtspUrl, bool turnNormal = true)
        {
            try
            {
                if (m_lRealHandle >= 0)
                {
                    CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);
                    m_lRealHandle = -1;
                }
                //CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);
            }
            catch (Exception ex) { }
            m_lRealHandle = -1;
            label_title.Text = "";
            label_picResult.Text = "";
            m_lUserID = -1;
            if(turnNormal)
            {
                panel_video.BackgroundImage = Properties.Resources.小监控窗口紫色;
            }

            if (index >= moniterArr.Count)
            {
                activeIndex = -1;
                isLiveShow = false;
                pictureBox.Invalidate();
                pictureBox.Image = null;
                return;
            }
            JToken j = moniterArr[index];
            rtspUrl = @"rtsp://" + j["deviceUser"].ToString() + ":" + j["devicePassword"].ToString() + "@" + j["deviceIp"].ToString();
            activeIndex = index;
            label_title.Text = j["monitorPointName"].ToString();
            int userId = userIdMap[j["monitorPointId"].ToString()];

            if ((hasNVR == "0" && userId == -1) ||
                (hasNVR == "1" && iChannelNum[index] == -1))
            {
                videoFail(pictureBox, ref isLiveShow, label_picResult, "登录失败,请检查网络!");
            }
            else
            {
                m_lUserID = userId;
                m_lRealHandle = preview(pictureBox.Handle, userId, index);
                isLiveShow = true;
                if (m_lRealHandle == -1)
                {
                    videoFail(pictureBox, ref isLiveShow, label_picResult, "预览失败!");
                }
                else
                {
                    label_picResult.Visible = false;
                }
            } 
        }
        bool lockAlarmForm = false;
        // 将报警视频框置红,如果当前4个不包含,切换第四个
        public void alarmVideo(int index)
        {
            if (activeIndex_1 == index && panel_video1.BackgroundImage != Properties.Resources.小监控窗口红色)
            {
                panel_video1.BackgroundImage = Properties.Resources.小监控窗口红色;
            }
            else if (activeIndex_2 == index && panel_video2.BackgroundImage != Properties.Resources.小监控窗口红色)
            {
                panel_video2.BackgroundImage = Properties.Resources.小监控窗口红色;
            }
            else if (activeIndex_3 == index && panel_video3.BackgroundImage != Properties.Resources.小监控窗口红色)
            {
                panel_video3.BackgroundImage = Properties.Resources.小监控窗口红色;
            }
            else if (activeIndex_4 == index && panel_video4.BackgroundImage != Properties.Resources.小监控窗口红色)
            {
                panel_video4.BackgroundImage = Properties.Resources.小监控窗口红色;
            }
            else
            {
                // 当前四框无,登录第4框
                new Thread(new ThreadStart(() =>
                {
                    if(!lockAlarmForm)
                    {
                        lockAlarmForm = true;
                        changeVideo(index, label_title4, label_picResult4, ref m_lUserID4, ref m_lRealHandle4, ref activeIndex_4, pictureBox4, panel_video4, ref isLiveShow_4, ref rtspUrl_4); // 报警
                        panel_video4.BackgroundImage = Properties.Resources.小监控窗口红色;
                        lockAlarmForm = false;
                    }
                })).Start();
            }
        }

        // 切换页
        public void changePage(int nowPage)
        {
            try
            {
                next_btn.Enabled = false;
                pre_btn.Enabled = false;
                txt_page.Text = (nowPage + 1).ToString() + "/" + (moniterArr.Count / 4 + (moniterArr.Count % 4 == 0 ? 0 : 1)).ToString() + "页";
                panel_video4.BackgroundImage = Properties.Resources.小监控窗口紫色;
                int index = nowPage * 4;
                new Thread(new ThreadStart(() =>
                {
                    try
                    {
                        new Thread(new ThreadStart(() =>
                        {
                            changeVideo(index, label_title1, label_picResult1, ref m_lUserID1, ref m_lRealHandle1, ref activeIndex_1, pictureBox1, panel_video1, ref isLiveShow_1, ref rtspUrl_1);
                        })).Start();
                        new Thread(new ThreadStart(() =>
                        {
                            changeVideo(index + 1, label_title2, label_picResult2, ref m_lUserID2, ref m_lRealHandle2, ref activeIndex_2, pictureBox2, panel_video2, ref isLiveShow_2, ref rtspUrl_2);
                        })).Start();
                        new Thread(new ThreadStart(() =>
                        {
                            changeVideo(index + 2, label_title3, label_picResult3, ref m_lUserID3, ref m_lRealHandle3, ref activeIndex_3, pictureBox3, panel_video3, ref isLiveShow_3, ref rtspUrl_3);
                        })).Start();
                        new Thread(new ThreadStart(() =>
                        {
                            lockAlarmForm = true;
                            changeVideo(index + 3, label_title4, label_picResult4, ref m_lUserID4, ref m_lRealHandle4, ref activeIndex_4, pictureBox4, panel_video4, ref isLiveShow_4, ref rtspUrl_4);
                            lockAlarmForm = false;
                        })).Start();

                        Thread.Sleep(3000);
                        next_btn.Enabled = true;
                        pre_btn.Enabled = true;
                    }
                    catch (Exception ex) { }
                })).Start();
            }
            catch (Exception ex) { }
        }

        // 重新登录
        public void reLogin(int index, Label label_title, Label label_picResult, ref Int32 m_lUserID,
            ref Int32 m_lRealHandle, ref int activeIndex, PictureBox pictureBox, Panel panel_video, ref bool isLiveShow, ref string rtspUrl)
        {
            next_btn.Enabled = false;
            pre_btn.Enabled = false;
            JToken j = moniterArr[index];
            if (j["deviceIp"].ToString() != "" && j["devicePort"].ToString() != "" && j["deviceUser"].ToString() != "" && j["devicePassword"].ToString() != "")
            {
                int userId = loginDevice(j["deviceIp"].ToString(), j["devicePort"].ToString(), j["deviceUser"].ToString(), j["devicePassword"].ToString());
                userIdMap[j["monitorPointId"].ToString()] = userId;
                changeVideo(index, label_title, label_picResult, ref m_lUserID, ref m_lRealHandle, ref activeIndex, pictureBox, panel_video, ref isLiveShow, ref rtspUrl); // 断线重登
            }
            next_btn.Enabled = true;
            pre_btn.Enabled = true;
        }

        private void label_picResult1_Click(object sender, EventArgs e) // 重登
        {
            reLogin(activeIndex_1, label_title1, label_picResult1, ref m_lUserID1, ref m_lRealHandle1, ref activeIndex_1, pictureBox1, panel_video1, ref isLiveShow_1, ref rtspUrl_1);
        }

        private void label_picResult2_Click(object sender, EventArgs e) // 重登
        {
            reLogin(activeIndex_2, label_title2, label_picResult2, ref m_lUserID2, ref m_lRealHandle2, ref activeIndex_2, pictureBox2, panel_video2, ref isLiveShow_2, ref rtspUrl_2);
         }

        private void label_picResult3_Click(object sender, EventArgs e) // 重登
        {
            reLogin(activeIndex_3, label_title3, label_picResult3, ref m_lUserID3, ref m_lRealHandle3, ref activeIndex_3, pictureBox3, panel_video3, ref isLiveShow_3, ref rtspUrl_3);
        }

        private void label_picResult4_Click(object sender, EventArgs e) // 重登
        {
            reLogin(activeIndex_4, label_title4, label_picResult4, ref m_lUserID4, ref m_lRealHandle4, ref activeIndex_4, pictureBox4, panel_video4, ref isLiveShow_4, ref rtspUrl_4);
        }
    }
}