SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: kanfv  
Дата: 16.06.10 04:53
Оценка:
Здравствуйте.
Тема получения иконок файлов по их типу по просторам инета расписана по шагам.
И я, писав кусок кода отвечающего за выдергивания иконок, думал проблем не будет...
Но не тут то было!
Вроде бы банальный код:
IImageList *p;
SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**) &p);
HICON hIcon;
HRESULT hr = p->GetIcon(0, ILD_NORMAL, &hIcon);

hIcon == NULL и hr == E_FAIL :???:

Причем, если вместо SHIL_JUMBO подставить SHIL_SMALL, SHIL_LARGE или SHIL_EXTRALARGE проблем нет!

IImageList во всех случаях заполняется корректно.
CoInitialize и CoInitializeEx пробовал в разных вариациях.
С FileIconInit игрался.
Пишу под Win 7 на VS 2008
Уж не знаю что и делать Помогите...
Re: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: CEMb  
Дата: 16.06.10 07:40
Оценка:
Здравствуйте, kanfv, Вы писали:

K>Уж не знаю что и делать Помогите...


Дурацкий вопрос: а в разбираемом файле иконки 256х256 есть вообще?
LoadImage(appInst, MAKEINTRESOURCE(id), IMAGE_ICON, 256, 256, LR_DEFAULTCOLOR) — что возвращает?
Re[2]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: kanfv  
Дата: 16.06.10 08:59
Оценка:
Тут LoadImage не помощник. Т.к. IImageList содержит иконки всех зарегистрированных файлов
в системе. Одну из иконок я и хочу получить по ее индексу(в моем примере индекс=0)
Re: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: KlugXP Россия
Дата: 16.06.10 09:50
Оценка:
Здравствуйте, kanfv, Вы писали:

K>И я, писав кусок кода отвечающего за выдергивания иконок, думал проблем не будет...

...
K>Пишу под Win 7 на VS 2008

Проблем и правда не должно быть.

Для начала — что будет, если в проводнике на рабочем столе выставить размер иконок больше 128x128 (Ctrl+Wheel Up)?

Что вернет
int count;
hr = p->GetImageCount(&count); ?


---
WBR
Re[2]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: kanfv  
Дата: 16.06.10 12:12
Оценка:
Здравствуйте, KlugXP, Вы писали:

KXP>Здравствуйте, kanfv, Вы писали:


K>>И я, писав кусок кода отвечающего за выдергивания иконок, думал проблем не будет...

KXP>...
K>>Пишу под Win 7 на VS 2008

KXP>Проблем и правда не должно быть.


KXP>Для начала — что будет, если в проводнике на рабочем столе выставить размер иконок больше 128x128 (Ctrl+Wheel Up)?


KXP>Что вернет

KXP>int count;
KXP>hr = p->GetImageCount(&count); ?


KXP>---

KXP>WBR

Выставил размер иконок на максимум. Результат тот же.

GetImageCount возвращает:
— если перед SHGetImageList вызвать FileIconInit(TRUE) count = 517
— если не вызывать FileIconInit или вызвать FileIconInit(FALSE) count = 8
— во всех трех случаях GetIcon = E_FAIL
Re[2]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: kanfv  
Дата: 16.06.10 12:14
Оценка:
Здравствуйте, KlugXP, Вы писали:

K>>Пишу под Win 7 на VS 2008


Еще закрадывается такая мысль: приложение Win32 а вот Windows 7 x64...
Re[3]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: CEMb  
Дата: 17.06.10 06:37
Оценка:
Здравствуйте, kanfv, Вы писали:

K>Тут LoadImage не помощник. Т.к. IImageList содержит иконки всех зарегистрированных файлов

K>в системе. Одну из иконок я и хочу получить по ее индексу(в моем примере индекс=0)

Я к тому, чтобы проверить, что в приложениях, которые содержать эти регистрированные икоки, эти иконки есть нужных размеров.
Re[3]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: KlugXP Россия
Дата: 17.06.10 09:53
Оценка:
Здравствуйте, kanfv, Вы писали:

K>Еще закрадывается такая мысль: приложение Win32 а вот Windows 7 x64...


Это без разницы.

Скорее всего забыт манифест.
To use IImageList::GetIcon, specify Comctl32.dll version 6 in the manifest.


Вот небольшой тест:


#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#define _WIN32_WINDOWS 0x0410
#define _WIN32_IE 0x0800


#include <windows.h>
#include <shellapi.h>
#include <commctrl.h>
#include <commoncontrols.h>

#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

#include <atlbase.h>

#define CALL(com_call)\
{\
    HRESULT hr___ = (com_call);\
    if (FAILED(hr___))\
        return hr___;\
}

static LPCTSTR szWindowClass = L"GS.ShellImageListTest.1";

HRESULT Paint_Shell_Icon_Impl(HDC hdc)
{
    int id = 0;//:first icon
    CComPtr<IImageList> shil;
    CALL(::SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&shil));
    int count;
    CALL(shil->GetImageCount(&count));
    if (count <= id)
        return E_UNEXPECTED;
    int x = 10, y = 10;
    int cx, cy;
    CALL(shil->GetIconSize(&cx, &cy));
    IMAGELISTDRAWPARAMS idp = {sizeof(idp), IImageListToHIMAGELIST(shil), id, hdc,
        x, y, cx, cy/*, 0, 0, CLR_NONE*/};
    idp.fStyle = ILD_TRANSPARENT;
    shil->Draw(&idp);

    HICON icon;
    CALL(shil->GetIcon(id, ILD_NORMAL, &icon));
    x += cx + 10;
    ::DrawIconEx(hdc, x, y, icon, cx, cy, 0, 0, DI_NORMAL);
    ::DestroyIcon(icon);
    return S_OK;
}

void Paint_Shell_Icon(HDC hdc)
{
    HRESULT hr = Paint_Shell_Icon_Impl(hdc);
    if (FAILED(hr))
    {
        OutputDebugString(L"error\r\n");
        __debugbreak();
    }
}

LRESULT CALLBACK Wnd_Proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = ::BeginPaint(hWnd, &ps);
            Paint_Shell_Icon(hdc);
            ::EndPaint(hWnd, &ps);
        }
        return 0;
    case WM_KEYDOWN:
        switch(wParam)
        {
        case VK_ESCAPE:
            ::PostMessage(hWnd, WM_CLOSE, 0, 0);
            break;
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE ,
                       LPTSTR    ,
                       int       nCmdShow)
{
    ::CoInitializeEx(0, COINIT_APARTMENTTHREADED);
    INITCOMMONCONTROLSEX icx = {sizeof(icx), ICC_STANDARD_CLASSES};
    ::InitCommonControlsEx(&icx);
    WNDCLASSEX wcex = {sizeof(WNDCLASSEX)};
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = Wnd_Proc;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SH_IMAGE_LIST_TEST));
    wcex.hIconSm        = ::LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    wcex.hCursor        = ::LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszClassName  = szWindowClass;
    ::RegisterClassEx(&wcex);

    HWND hWnd = CreateWindow(szWindowClass, L"Jumbo-Mumbo", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    ::ShowWindow(hWnd, nCmdShow);
    ::UpdateWindow(hWnd);

    for (MSG msg; ::GetMessage(&msg, NULL, 0, 0); )
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
    ::CoUninitialize();
    return 0;
}

#pragma comment(linker,"/manifestdependency:\"type='win32'\
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'\
processorArchitecture='*' publicKeyToken='6595b64144ccf1df'\
language='*'\"")


Другое дело, что иконка в DrawIconEx визуально отличается от той, что нарисована в методе Draw...



---
WBR
Re[4]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: kanfv  
Дата: 18.06.10 16:39
Оценка:
Спасибо. Скомпилил Ваш пример в Unicode. Интересные результаты:
— в Dubug версии вылетает с ошибкой(!!!)
— в Release версии все нормально отрабатывает. Показывает окно как у Вас.
Что бы это значило...?
Re[5]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: KlugXP Россия
Дата: 19.06.10 15:30
Оценка:
Здравствуйте, kanfv, Вы писали:

K>Спасибо. Скомпилил Ваш пример в Unicode. Интересные результаты:

K>- в Dubug версии вылетает с ошибкой(!!!)
K>- в Release версии все нормально отрабатывает. Показывает окно как у Вас.
K>Что бы это значило...?

Работало и в Debug и в Release.
На всякий случай тут весь прожект (VS 2005):
http://svn2.xp-dev.com/svn/sh_image_list_test/

---
WBR
Re[6]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: kanfv  
Дата: 20.06.10 13:14
Оценка:
Здравствуйте, KlugXP, Вы писали:

KXP>Здравствуйте, kanfv, Вы писали:


K>>Спасибо. Скомпилил Ваш пример в Unicode. Интересные результаты:

K>>- в Dubug версии вылетает с ошибкой(!!!)
K>>- в Release версии все нормально отрабатывает. Показывает окно как у Вас.
K>>Что бы это значило...?

KXP>Работало и в Debug и в Release.

KXP>На всякий случай тут весь прожект (VS 2005):
KXP>http://svn2.xp-dev.com/svn/sh_image_list_test/

KXP>---

KXP>WBR

Debug версия ни в какую
Re[7]: SHGetImageList(SHIL_JUMBO,...) и GetIcon
От: KlugXP Россия
Дата: 21.06.10 09:37
Оценка:
Здравствуйте, kanfv, Вы писали:

K>Debug версия ни в какую


Ну так и откройте (для себя) event log и разберитесь с манифестами. Проблема явно не относится к теме. Возможно это вирус.

---
WBR
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.