WIA в Delphi. Частина 3. Список пристроїв, параметри пристрою
В цій статті дізнаємось як отримати список пристроїв та налаштувати їх параметри перед скануванням. Головним об’єктом, призначеним для цього є
Device
Активне з’єднання з пристроєм. За допомогою цього об’єкту виконується Безпосередня робота та налаштування параметрів пристрою, читання його технічних характеристик.
Незмінювані властивості пристрою, такі як назва, виробник, інформація щодо драйверів, портів, розташування і тому подібне міститься к колекції Device.Properties.
Змінювані властивості, наприклад, роздільна здатність, кольорова схема, межі сканування, формат даних тощо, містяться в іншій колекції – Device.Items.
DeviceManager
Об’єкт керує пристроями обробки зображень, підключеними до комп’ютера. Містить властивість DeviceInfos, об’єкт, за допомогою якого відбувається підключення до конкретного пристрою для налаштування, роботи та отримання інформації.
DeviceInfos
Колекція всіх пристроїв обробки зображень, підключених до цього комп’ютера.
Count
Кількість пристроїв.
Item
Пристрій у вигляді об’єкту Device.
DeviceInfo
Описує деякі властивості пристрою (идентифікатор, тип) та містить єдиний метод Connect.
Connect
Встановлює з’єднання з пристроєм. Метод повертає об’єкт Device.
Приклад роботи із списком пристроїв:
var
lCommonDialog: ICommonDialog;
lDeviceManager: IDeviceManager;
lDevice: IDevice;
di: Integer;
di_v: OLEVariant;
...
lCommonDialog := CoCommonDialog.Create;
lDeviceManager := CoDeviceManager.Create;
if (lDeviceManager <> nil) and (lDeviceManager.DeviceInfos.Count > 0) then
// Індекси пристроїв починаються з 1, а не з 0!
for di := 1 to lDeviceManager.DeviceInfos.Count do
begin
di_v := di;
// підключення до пристрою
lDevice := lDeviceManager.DeviceInfos.Item[di_v].Connect;
if lDevice <> nil then
begin
// підключення відбулося вдало
end;
end;
Property
Об’єкт, що містить певну властивість.
IsReadOnly
Вказує, що значення властивості доступне лише для читання.
Name
Назва властивості.
type_
Тип властивості:
UnsupportedPropertyType | Значення властивості не підтримується |
BooleanPropertyType | Boolean |
BytePropertyType | Byte |
IntegerPropertyType | Integer |
UnsignedIntegerPropertyType | Cardinal |
LongPropertyType | Int64 |
UnsignedLongPropertyType | UInt64 |
ErrorCodePropertyType | Int64, код помилки |
LargeIntegerPropertyType | Int64 |
UnsignedLargeIntegerPropertyType | UInt64 |
SinglePropertyType | Single |
DoublePropertyType | Double |
CurrencyPropertyType | Currency |
DatePropertyType | TDateTime |
FileTimePropertyType | TDateTime |
ClassIDPropertyType | String |
StringPropertyType | String |
ObjectPropertyType | Значенням властивості є об'єкт |
HandlePropertyType | Integer (THandle) |
VariantPropertyType | Variant |
Типи, описані як VectorOf... є массивами значень відповідного типу, наприклад, VectorOfBytesPropertyType – масив значень типу Byte.
PropertyID
Ідентифікатор властивості. Число, одне і те саме для однотипних властивостей різних пристроїв.
Get_Value
Функція, що отримує значення властивості.
Item
Об’єкт майже аналогічний об’єкту Property і містить аналогічні властивості.
ItemID
Ідентифікатор елементу.
Приклад читання властивостей пристроїв:
var
lCommonDialog: ICommonDialog;
lDeviceManager: IDeviceManager;
lDevice: IDevice;
lProperties: IProperties;
lItems: IItems;
di, propi: Integer;
di_v, propi_v: OLEVariant;
PropType: TVarType;
PropName: WideString;
PropValue: OleVariant;
PropID: Integer;
...
Memo1.Clear;
lCommonDialog := CoCommonDialog.Create;
lDeviceManager := CoDeviceManager.Create;
if (lDeviceManager <> nil) and (lDeviceManager.DeviceInfos.Count > 0) then
for di := 1 to lDeviceManager.DeviceInfos.Count do
begin
di_v := di;
// підключення до пристрою
Memo1.Lines.Add('Device #' + IntToStr(di));
lDevice := lDeviceManager.DeviceInfos.Item[di_v].Connect;
if lDevice <> nil then
begin
// Незмінювані властивості
Memo1.Lines.Add('Properties');
lProperties := lDevice.Properties;
if (lProperties <> nil) and (lProperties.Count > 0) then
for propi := 1 to lProperties.Count do
begin
propi_v := propi;
// назва
PropName := lProperties.Item[propi_v].Name;
// значення
PropValue := lProperties.Item[propi_v].Get_Value;
// фактичний тип значення властивості
PropType := PropValue;
// ID
PropID := lProperties.Item[propi_v].PropertyID;
// відображення властивості
Memo1.Lines.Add(Format('[%d] (%s) %s = %s', [PropID, VarTypeToStr(PropType), PropName, VarToStr(PropValue)]));
end;
// Змінювані властивості
Memo1.Lines.Add('Items');
lItems := lDevice.Items;
if (lItems <> nil) and (lItems.Count > 0) and (lItems.Item[1].Properties.Count > 0) then
for devpi := 1 to lItems.Item[1].Properties.Count do
begin
propi_v := propi;
// назва
PropName := lItems.Item[1].Properties.Item[propi_v].Name;
// значення
PropValue := lItems.Item[1].Properties.Item[propi_v].Get_Value;
// фактичний тип значення властивості
PropType := VarType(PropValue);
// ID
PropID := lItems.Item[1].Properties.Item[propi_v].PropertyID;
// відображення властивості
Memo1.Lines.Add(Format('[%d] (%s) %s = %s', [PropID, VarTypeToStr(PropType), PropName, VarToStr(PropValue)]));
end;
end;
end;
Функції VarTypeToStr та VarToStr доступні в файлі varutls.pas.
Діапазони та списки значень
Об’єкт Property містить також інші властивості, які дозволяють отримати інформацію не тільки щодо конкретного значення, а й щодо діапазону можливих значень властивості чи їх переліку. Таким чином, наприклад, можна дізнатися які саме кольорові схеми підтримує пристрій чи який діапазон його роздільної здатності.
SubType
Підтип власності:
UnspecifiedSubType | Властивість не має підтипу |
RangeSubType | Властивість приймає діапазон значень від SubTypeMin до SubTypeMax в кроках SubTypeStep |
ListSubType | Властивість приймає одне зі списку значень, перерахованих у SubTypeValues |
FlagSubType | Значення у вигляді переліку бітів (прапорців), вказане у SubTypeValues |
SubTypeDefault
Значення властивості за замовчуванням.
Приклад відображення значень властивостей з діапазонами і списками:
var
lCommonDialog: ICommonDialog;
lDeviceManager: IDeviceManager;
lDevice: IDevice;
lProperties: IProperties;
lItems: IItems;
di, propi, li: Integer;
di_v, propi_v, li_v: OLEVariant;
PropType: TVarType;
PropName: WideString;
PropValue, SubPropValue: OleVariant;
PropID: Integer;
PropSubType: WiaSubType;
psp_min, psp_max, psp_step: Integer;
...
Memo1.Clear;
lCommonDialog := CoCommonDialog.Create;
lDeviceManager := CoDeviceManager.Create;
if (lDeviceManager <> nil) and (lDeviceManager.DeviceInfos.Count > 0) then
for di := 1 to lDeviceManager.DeviceInfos.Count do
begin
di_v := di;
// підключення до пристрою
Memo1.Lines.Add('Device #' + IntToStr(di));
lDevice := lDeviceManager.DeviceInfos.Item[di_v].Connect;
if lDevice <> nil then
begin
// Незмінювані властивості
Memo1.Lines.Add('Properties');
lProperties := lDevice.Properties;
if (lProperties <> nil) and (lProperties.Count > 0) then
for propi := 1 to lProperties.Count do
begin
propi_v := propi;
// назва
PropName := lProperties.Item[propi_v].Name;
// значення
PropValue := lProperties.Item[propi_v].Get_Value;
// фактичний тип значення властивості
PropType := PropValue;
// ID
PropID := lProperties.Item[propi_v].PropertyID;
// відображення властивості
Memo1.Lines.Add(Format('[%d] (%s) %s = %s', [PropID, VarTypeToStr(PropType), PropName, VarToStr(PropValue)]));
end;
// Змінювані властивості
Memo1.Lines.Add('Items');
lItems := lDevice.Items;
if (lItems <> nil) and (lItems.Count > 0) and (lItems.Item[1].Properties.Count > 0) then
for devpi := 1 to lItems.Item[1].Properties.Count do
begin
propi_v := propi;
// назва
PropName := lItems.Item[1].Properties.Item[propi_v].Name;
// значення
PropValue := lItems.Item[1].Properties.Item[propi_v].Get_Value;
// фактичний тип значення властивості
PropType := VarType(PropValue);
// ID
PropID := lItems.Item[1].Properties.Item[propi_v].PropertyID;
// підтип
PropSubType := lItems.Item[1].Properties.Item[propi_v].SubType;
// відображення властивості
Memo1.Lines.Add(Format('[%d] (%s) %s = %s', [PropID, VarTypeToStr(PropType), PropName, VarToStr(PropValue)]));
// підтип
case PropSubType of
// діапазон значень
RangeSubType:
begin
psp_min := lItems.Item[1].Properties.Item[propi_v].SubTypeMin;
psp_max := lItems.Item[1].Properties.Item[propi_v].SubTypeMax;
psp_step := lItems.Item[1].Properties.Item[propi_v].SubTypeStep;
// відображення діапазону та кроку
Memo1.Lines.Add(Format('[range] %d - %d (%d)', [psp_min, psp_max, psp_step]));
end;
// список значень
ListSubType:
if lItems.Item[1].Properties.Item[propi_v].SubTypeValues.Count > 0 then
begin
Memo1.Lines.Add('[list]');
for li := 1 to lItems.Item[1].Properties.Item[propi_v].SubTypeValues.Count do
begin
v_li := li;
SubPropValue := lItems.Item[1].Properties.Item[propi_v].SubTypeValues.Get_Item(li_v);
// відображення списку
Memo1.Lines.Add(VarToStr(SubPropValue));
end;
end;
end;
end;
end;
end;
Зміна значень властивостей здійснюється за допомогою методу Set_Value, якому передається змінна типу OleVariant із встановленим необхідним значенням.
Наприклад, так можна встановити роздільну здатність для пристрою:
const
WIA_DPS_HORIZONTAL_RESOLUTION = 6147; // PropertyID
WIA_DPS_VERTICAL_RESOLUTION = 6148; // PropertyID
var
RVal: OleVariant;
...
RVal := 300;
if lItems.Item[1].Properties.Item[propi_v].PropertyID = WIA_DPS_HORIZONTAL_RESOLUTION then
lItems.Item[1].Properties.Item[propi_v].Set_Value(RVal);
if lItems.Item[1].Properties.Item[propi_v].PropertyID = WIA_DPS_VERTICAL_RESOLUTION then
lItems.Item[1].Properties.Item[propi_v].Set_Value(RVal);
Останні коментарі