Иконки устройств (принтеров) в Windows 7
От: nicestep Россия  
Дата: 07.07.11 11:48
Оценка:
"Windows 7 снабжена новым иконочным дополнением. /.../Самое любопытное, что коллекция — пополняемая. Иконки не поставляются вместе с самой системой. ОС хранит лишь стандартные универсальные иконки (их можно посмотреть в виде одного большого файла). Но при установке устройства, Windows 7 обращается на сервер Microsoft и скачивает оттуда мета-данные. Помимо сервисной и технической информации, ОС загружает и фирменную иконку, уникальную для каждого аппаратного компонента." ©

В своем приложении для получения иконок принтеров, установленных в системе, использую интерфейс IExtractIcon. Но даже перепробовав все флаги для GetIconLocation получаю только стандартные иконки.



Каким образом можно получить те самые "пополняемые" иконки для того или иного устройства?
Re: Иконки устройств (принтеров) в Windows 7
От: nicestep Россия  
Дата: 08.07.11 10:53
Оценка:
N>Каким образом можно получить те самые "пополняемые" иконки для того или иного устройства?

После продолжительного гугления, появились следующие догадки. Я в приложении перебираю элементы папки, полученной с помощью SHGetSpecialFolderLocation с параметром CSIDL_PRINTERS. Но, как оказалось, начиная с Windows Vista эта функция оставлена лишь для обратной совместимости. Теперь я пробую зайти в папку "Устройства и принтеры" панели управления, но возникают проблемы при получении IShellItem — функция IOpenControlPanel.GetPath возвращает ошибку в выделенной строке


const
  DEVICES_AND_PRINTERS = 'Microsoft.DevicesAndPrinters';
var
  StrBuf: array[0..MAX_PATH - 1] of Char;
  ControlPanel: IOpenControlPanel;
  ShellItem: IShellItem2;
  Walk: INamespaceWalk;
  MyWalk: TMyNamespaceWalkCB;
  HR: HRESULT;
begin
  HR := CoCreateInstance(CLSID_OpenControlPanel, nil,
    CLSCTX_INPROC_SERVER, IOpenControlPanel, ControlPanel);
  CheckShellResult('CoCreateInstance(CLSID_OpenControlPanel)', HR);
  try
    HR := ControlPanel.GetPath(DEVICES_AND_PRINTERS, StrBuf, MAX_PATH);
    CheckShellResult('ControlPanel.GetPath', HR);
    HR := SHCreateItemFromParsingName(StrBuf, nil, IShellItem2, ShellItem);
    CheckShellResult('SHCreateItemFromParsingName', HR);
    ...
Re[2]: Иконки устройств (принтеров) в Windows 7
От: De-Bugger  
Дата: 08.07.11 12:00
Оценка:
Здравствуйте, nicestep, Вы писали:

N>После продолжительного гугления, появились следующие догадки. Я в приложении перебираю элементы папки, полученной с помощью SHGetSpecialFolderLocation с параметром CSIDL_PRINTERS. Но, как оказалось, начиная с Windows Vista эта функция оставлена лишь для обратной совместимости. Теперь я пробую зайти в папку "Устройства и принтеры" панели управления, но возникают проблемы при получении IShellItem — функция IOpenControlPanel.GetPath возвращает ошибку в выделенной строке


Не знаю, у меня код работает, возвращает ::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}
CoInitialize(NULL); не забыли? Какой код ошибки вообще?
Re[3]: Иконки устройств (принтеров) в Windows 7
От: nicestep Россия  
Дата: 11.07.11 03:45
Оценка:
Здравствуйте, De-Bugger, Вы писали:

DB>Не знаю, у меня код работает, возвращает ::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}

DB>CoInitialize(NULL); не забыли? Какой код ошибки вообще?

Добавил себе CoInitialize, хотя, мне кажется, это лишнее

 HR := CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
  if HR in [S_OK, S_FALSE] then
    try
      HR := CoCreateInstance(CLSID_OpenControlPanel, nil,
        CLSCTX_INPROC_SERVER, IOpenControlPanel, ControlPanel);
      CheckShellResult('CoCreateInstance(CLSID_OpenControlPanel)', HR);
      try
        HR := ControlPanel.GetPath(DEVICES_AND_PRINTERS, StrBuf, MAX_PATH); // <<<


Возвращает многозначительное E_FAIL
Re[3]: Иконки устройств (принтеров) в Windows 7
От: nicestep Россия  
Дата: 11.07.11 06:09
Оценка:
Здравствуйте, De-Bugger, Вы писали:

DB>Не знаю, у меня код работает, возвращает ::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}

DB>CoInitialize(NULL); не забыли? Какой код ошибки вообще?

Выяснилось, что код работает только в 32-битной версии Windows. Ошибка, соответственно, возникает только в 64-битной. Скомпилировать в Delphi в x64 [пока] нельзя. Может есть к-н решение?
Re[4]: Иконки устройств (принтеров) в Windows 7
От: De-Bugger  
Дата: 12.07.11 11:03
Оценка:
Здравствуйте, nicestep, Вы писали:

N>Здравствуйте, De-Bugger, Вы писали:


DB>>Не знаю, у меня код работает, возвращает ::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}

DB>>CoInitialize(NULL); не забыли? Какой код ошибки вообще?

N>Выяснилось, что код работает только в 32-битной версии Windows. Ошибка, соответственно, возникает только в 64-битной. Скомпилировать в Delphi в x64 [пока] нельзя. Может есть к-н решение?

Да. Написать простенькое приложение на C/C++ и скомпилировать его для 32 и 64 битов. Реализовать IPC канал взаимодействия между основным приложением на Делфи и этой вспомогательной приблудой.
Ну еще можно попробовать лазарус, но я бы не стал его трогать
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.