////////////////////////////////////////////////////////////////////////////////////////////////

        public bool    Sub_Connect(CInfo_Camera_Factory info)
        {
            Sub_Disconnect();

            switch (info.m_temaker)
            {
            case EMAKER.eHik:
                if (_Idriver_factory_Hik.Get_Exist(info) == false)
                {
                    return(false);
                }

                _Idriver_camera = _Idriver_factory_Hik.Set_Connect(info);

                break;

            case EMAKER.eBasler:
                if (_Idriver_factory_Basler.Get_Exist(info) == false)
                {
                    return(false);
                }

                _Idriver_camera = _Idriver_factory_Basler.Set_Connect(info);

                break;
            }

            _Idriver_camera.ImageGrabbed = _Sub_Set_Grabbed;
            _Ilogger.Info("Connect");

            return(true);
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public IDriver_Camera_Control   Set_Connect(CInfo_Camera_Factory CameraInfo)
        {
            if (Get_Exist(CameraInfo) == false)
            {
                return(null);
            }

            MyCamera.MV_CC_DEVICE_INFO stDevInfo;
            if (GetHikDeviceInfo(CameraInfo, out stDevInfo) == false)
            {
                return(null);
            }

            var device = new MyCamera();

            if (MyCamera.MV_OK != device.MV_CC_CreateDevice_NET(ref stDevInfo))
            {
                return(null);
            }


            if (MyCamera.MV_OK != device.MV_CC_OpenDevice_NET())
            {
                return(null);
            }

            if (CameraInfo.m_teinterface == EINTERFACE.eGIGE)
            {
                int nPacketSize = device.MV_CC_GetOptimalPacketSize_NET();
                if (nPacketSize > 0)
                {
                    if (MyCamera.MV_OK != device.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize))
                    {
                        return(null);
                    }
                }
                else
                {
                    return(null);
                }
            }

            var info = new MyCamera.MV_IMAGE_BASIC_INFO();

            if (MyCamera.MV_OK != device.MV_CC_GetImageInfo_NET(ref info))
            {
                return(null);
            }

            var camera = new Control_HikCamera(device, info);

            if (MyCamera.MV_OK != device.MV_CC_RegisterImageCallBackEx_NET(Control_HikCamera.ImageCallback, GCHandle.ToIntPtr(camera.Handle)))
            {
                return(null);
            }

            return(camera);
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public bool                                             Get_Exist(CInfo_Camera_Factory CameraInfo)
        {
            if (CameraInfo.m_temaker != EMAKER.eHik)
            {
                return(false);
            }

            MyCamera.MV_CC_DEVICE_INFO stDevInfo;
            return(GetHikDeviceInfo(CameraInfo, out stDevInfo));
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public IDriver_Camera_Control   Set_Connect(CInfo_Camera_Factory cameraInfo)
        {
            var baslerInfo = GetBaslerInfo(cameraInfo);

            if (baslerInfo == null)
            {
                return(null);
            }

            return(new Control_BaslerCamera(baslerInfo));
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static bool                              GetHikDeviceInfo(CInfo_Camera_Factory CameraInfo, out MyCamera.MV_CC_DEVICE_INFO stDevInfo)
        {
            stDevInfo = new MyCamera.MV_CC_DEVICE_INFO();

            var stDevList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
            var nRet      = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref stDevList);

            if (MyCamera.MV_OK != nRet)
            {
                return(false);
            }

            for (Int32 i = 0; i < stDevList.nDeviceNum; i++)
            {
                stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));

                switch (CameraInfo.m_teinterface)
                {
                case EINTERFACE.eUSB:
                    if (MyCamera.MV_USB_DEVICE == stDevInfo.nTLayerType)
                    {
                        var stUsb3DeviceInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO));

                        if (CameraInfo.m_strmodel == stUsb3DeviceInfo.chModelName &&
                            CameraInfo.m_strserial == stUsb3DeviceInfo.chSerialNumber)
                        {
                            return(true);
                        }
                    }

                    break;

                case EINTERFACE.eGIGE:
                    if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
                    {
                        var stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));

                        if (CameraInfo.m_strmodel == stGigEDeviceInfo.chModelName &&
                            CameraInfo.m_strserial == stGigEDeviceInfo.chSerialNumber)
                        {
                            return(true);
                        }
                    }

                    break;
                }
            }

            return(false);
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public bool                                             Get_Exist(CInfo_Camera_Factory CameraInfo)
        {
            if (CameraInfo.m_temaker != EMAKER.eBasler)
            {
                return(false);
            }

            var infos = Get_Devices();

            return(infos.Any(i
                             => i.m_temaker == CameraInfo.m_temaker &&
                             i.m_teinterface == CameraInfo.m_teinterface &&
                             i.m_strmodel == CameraInfo.m_strmodel &&
                             i.m_strserial == CameraInfo.m_strserial));
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private Basler.Pylon.ICameraInfo GetBaslerInfo(CInfo_Camera_Factory info)
        {
            if (info.m_temaker != EMAKER.eBasler)
            {
                return(null);
            }

            List <Basler.Pylon.ICameraInfo> cameraInfos = Basler.Pylon.CameraFinder.Enumerate();

            foreach (var baslerInfo in cameraInfos)
            {
                var type = baslerInfo[Basler.Pylon.CameraInfoKey.DeviceType];
                switch (info.m_teinterface)
                {
                case EINTERFACE.eUSB:
                    if (type == "BaslerUsb" &&
                        baslerInfo[Basler.Pylon.CameraInfoKey.ModelName] == info.m_strmodel &&
                        baslerInfo[Basler.Pylon.CameraInfoKey.SerialNumber] == info.m_strserial)
                    {
                        return(baslerInfo);
                    }

                    break;

                case EINTERFACE.eGIGE:
                    if (type == "BaslerGigE" &&
                        baslerInfo[Basler.Pylon.CameraInfoKey.ModelName] == info.m_strmodel &&
                        baslerInfo[Basler.Pylon.CameraInfoKey.SerialNumber] == info.m_strserial)
                    {
                        return(baslerInfo);
                    }

                    break;
                }
            }

            return(null);
        }