Beispiel #1
0
 static RawKeyboardState()
 {
     _objectsFormat = new ObjectDataFormat[256];
     for (int i = 0; i < _objectsFormat.Length; i++)
     {
         _objectsFormat[i] = new ObjectDataFormat(ObjectGuid.Key,
                                                  i,
                                                  DeviceObjectTypeFlags.PushButton | DeviceObjectTypeFlags.ToggleButton | DeviceObjectTypeFlags.Optional,
                                                  ObjectDataFormatFlags.None, i)
         {
             Name = "Key" + i
         };
     }
 }
        private unsafe DataFormat GetDataFormat <TRaw>() where TRaw : unmanaged
        {
            if (_dataFormat == null)
            {
                // Build DataFormat from IDataFormatProvider
                if (typeof(IDataFormatProvider).IsAssignableFrom(typeof(TRaw)))
                {
                    var provider = (IDataFormatProvider)(new TRaw());
                    _dataFormat = new DataFormat(provider.Flags)
                    {
                        DataSize      = sizeof(TRaw),
                        ObjectsFormat = provider.ObjectsFormat
                    };
                }
                else
                {
                    // Build DataFormat from DataFormat and DataObjectFormat attributes
                    IEnumerable <DataFormatAttribute> dataFormatAttributes = typeof(TRaw).GetCustomAttributes <DataFormatAttribute>(false);
                    if (dataFormatAttributes.Count() != 1)
                    {
                        throw new InvalidOperationException(
                                  string.Format(System.Globalization.CultureInfo.InvariantCulture, "The structure [{0}] must be marked with DataFormatAttribute or provide a IDataFormatProvider",
                                                typeof(TRaw).FullName));
                    }

                    _dataFormat = new DataFormat(((DataFormatAttribute)dataFormatAttributes.First()).Flags)
                    {
                        DataSize = sizeof(TRaw)
                    };

                    var dataObjects = new List <ObjectDataFormat>();

                    IEnumerable <FieldInfo> fields = typeof(TRaw).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

                    // Iterates on fields
                    foreach (var field in fields)
                    {
                        IEnumerable <DataObjectFormatAttribute> dataObjectAttributes = field.GetCustomAttributes <DataObjectFormatAttribute>(false);
                        if (dataObjectAttributes.Count() > 0)
                        {
                            int fieldOffset         = Marshal.OffsetOf(typeof(TRaw), field.Name).ToInt32();
                            int totalSizeOfField    = Marshal.SizeOf(field.FieldType);
                            int offset              = fieldOffset;
                            int numberOfDataObjects = 0;

                            // Count the number of effective sub-field for a field
                            // A field that contains a fixed array should have sub-field
                            for (int i = 0; i < dataObjectAttributes.Count(); i++)
                            {
                                var attr = dataObjectAttributes.ElementAt(i);
                                numberOfDataObjects += attr.ArrayCount == 0 ? 1 : attr.ArrayCount;
                            }

                            // Check that the size of the field is compatible with the number of sub-field
                            // For a simple field without any array element, sub-field = field
                            int sizeOfField = totalSizeOfField / numberOfDataObjects;
                            if ((sizeOfField * numberOfDataObjects) != totalSizeOfField)
                            {
                                throw new InvalidOperationException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Field [{0}] has incompatible size [{1}] and number of DataObjectAttributes [{2}]", field.Name, (double)totalSizeOfField / numberOfDataObjects, numberOfDataObjects));
                            }

                            int subFieldIndex = 0;

                            // Iterates on attributes
                            for (int i = 0; i < dataObjectAttributes.Count(); i++)
                            {
                                var attr = dataObjectAttributes.ElementAt(i);
                                numberOfDataObjects = attr.ArrayCount == 0 ? 1 : attr.ArrayCount;

                                // Add DataObjectFormat
                                for (int j = 0; j < numberOfDataObjects; j++)
                                {
                                    var dataObject = new ObjectDataFormat(
                                        string.IsNullOrEmpty(attr.Guid) ? Guid.Empty : new Guid(attr.Guid), offset,
                                        attr.TypeFlags, attr.Flags, attr.InstanceNumber);

                                    // Use attribute name or fallback to field's name
                                    string name = (string.IsNullOrEmpty(attr.Name)) ? field.Name : attr.Name;
                                    name = numberOfDataObjects == 1 ? name : name + subFieldIndex;

                                    dataObject.Name = name;
                                    dataObjects.Add(dataObject);

                                    offset += sizeOfField;
                                    subFieldIndex++;
                                }
                            }
                        }
                    }
                    _dataFormat.ObjectsFormat = dataObjects.ToArray();
                }

                for (int i = 0; i < _dataFormat.ObjectsFormat.Length; i++)
                {
                    var dataObject = _dataFormat.ObjectsFormat[i];

                    // Map field name to object
                    if (_mapNameToObjectFormat.ContainsKey(dataObject.Name))
                    {
                        throw new InvalidOperationException(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Incorrect field name [{0}]. Field name must be unique", dataObject.Name));
                    }
                    _mapNameToObjectFormat.Add(dataObject.Name, dataObject);
                }

                // DumpDataFormat(_dataFormat);
            }
            return(_dataFormat);
        }