Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ListView, ImageList, Icons 16-bit 
:(
    Опции темы
Alca
Дата 21.1.2013, 01:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Как-то криво отображаются иконки при 16-битном системном цвете. Как пофиксить?
Кода много, поэтому выложу пока это, если необходим какой-то конкретный кусок,
то могу дописать.

Код

//  ImageList
list_images = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR16, 40, 80);

Код

/*
 * We use 32bpp images for menu. After these images are loaded from resources
 * the RGB values should be multiple to alpha to allow system to show ARGB
 * bitmaps correctly.
 */
HBITMAP 
pre_multiple_rgb(
    HBITMAP hsrc, 
    WORD    wBitsPixel
)
{
    HBITMAP hold = NULL;
    HDC hdcsrc = NULL;
    HDC hdc = GetDC(m_hMainDlg);
    BITMAPINFOHEADER bi;
    BITMAP bmp;
    BITMAPINFO bmi;
    HBITMAP dib = NULL;;
    UCHAR *dst = NULL;
    UCHAR *src, *tmp;
    UCHAR alpha;
    int bpl;
    ULONG x, y;
    DWORD bmp_size = 0;
    HANDLE hdib = NULL;
    char *lpbitmap = NULL;

    hdcsrc = CreateCompatibleDC(hdc);
    hold   = (HBITMAP)SelectObject(hdcsrc, hsrc);
    
    GetObject(hsrc, sizeof(BITMAP), &bmp);

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmp.bmWidth;;
    bi.biHeight = bmp.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = wBitsPixel;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    bmp_size = ((bmp.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp.bmHeight;
    hdib = GlobalAlloc(GHND, bmp_size);

    lpbitmap = (char *)GlobalLock(hdib);

    /* Get bits of source bitmap. */
    GetDIBits(hdcsrc, hsrc, 0, bmp.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS))

    /* For destination bitmap */
    bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
    bmi.bmiHeader.biWidth = bmp.bmWidth;
    bmi.bmiHeader.biHeight = bmp.bmHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = wBitsPixel;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = 0;
    bmi.bmiHeader.biXPelsPerMeter = 0;
    bmi.bmiHeader.biYPelsPerMeter = 0;
    bmi.bmiHeader.biClrUsed = 0;
    bmi.bmiHeader.biClrImportant = 0;

    dib = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&dst, NULL,    0);

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            alpha = tmp[3];

            dst[0] = tmp[0] * alpha / 255;
            dst[1] = tmp[1] * alpha / 255;
            dst[2] = tmp[2] * alpha / 255;
            dst[3] = alpha;

            dst += 4;
            tmp += 4;
        }
    }

stop_rgb:
    SelectObject(hdcsrc, hold);
    DeleteDC(hdcsrc);

    if (hdib) {
        GlobalUnlock(hdib);
        GlobalFree(hdib);
    }

    return dib;
}


Это сообщение отредактировал(а) Alca - 21.1.2013, 02:26

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  Pic.PNG 7,07 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 21.1.2013, 04:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



ImageList Transparency on Listviews?

Цитата

First up, ImageList_ReplaceIcon copies the icon data when adding it to an image list. So the HICON needs to be released afterwards.

Next, imagelists are natively bitmaps, not icons. And the way you are creating your imagelist makes the conversion of icon to bitmap very ambiguous. ILC_COLOR32 implies the imagelist should be created as a 32bit dib section, which typically contain transparency information via an embedded alpha channel. ILC_MASK instead implies that the internal bitmaps are DDB bitmaps, with the transparency information stored as a 1bpp mask bitmap.

The quickest solution to your problem - take your two icons:
Merge them into a single bitmap resource thats 32 pels wide by 16 high. Fill the background with a mask color :- purple or something.
Create the bitmap using ILC_COLOR|ILC_MASK
Load the bitmap being sure NOT to use LR_TRANSPARENT.
Add the bitmap using ImageList_AddMasked passing in a COLORREF that represents the mask color.

OR, for a better visual effect...
export your PNG data as a 32x16 32bpp bitmap file containing pre-multiplied alpha channel data.
Create the imagelist using the ILC_COLOR32 value.
LoadImage() with LR_CREATEDIBSECTION to load the bitmap as a 32bpp dib section.
Add the image using ImageList_Add()

(the last option is kind of tricky as the number of tools that support writing out 32bit bmp files with properly pre multiplied alpha channels is rather low).



Edited to add the following code sample. Using a 4bpp bitmap created in the dev environment this works just great :-
Код

HWND hwndCtl = CreateWindowEx(0,WC_LISTVIEW,TEXT("ListView1"),WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL,0,0,cx,cy,hWnd,(HMENU)101,hModule,NULL);
HBITMAP hbm = (HBITMAP)LoadImage(hModule,MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,0);
COLORREF crMask=RGB(255,0,255);
HIMAGELIST himl = ImageList_Create(16,16,ILC_COLOR|ILC_MASK,2,0);
ImageList_AddMasked(himl,hbm,crMask);
ListView_SetImageList(hwndCtl,himl,LVSIL_NORMAL);



Это сообщение отредактировал(а) Alca - 21.1.2013, 12:31


--------------------
PM WWW ICQ Skype Jabber   Вверх
feodorv
Дата 21.1.2013, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Так в чём суть-то? В том. что не нужно ILC_COLOR16, а нужно ILC_COLOR?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
artsb
Дата 21.1.2013, 08:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(Alca @  21.1.2013,  01:51 Найти цитируемый пост)
    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            alpha = tmp[3];
            dst[0] = tmp[0] * alpha / 255;
            dst[1] = tmp[1] * alpha / 255;
            dst[2] = tmp[2] * alpha / 255;
            dst[3] = alpha;
            dst += 4;
            tmp += 4;
        }
    }

Это не правильно, ИМХО. Вы преобразуете 32bit битмап в 16bit битмап. Вы подразучеваете, что 16bit битмапе тоже 4 байта для представления цвета. Но это не так - High color (15/16-bit). Как следует из названия, там всего лишь 2 байта.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alca
Дата 21.1.2013, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Цитата

Так в чём суть-то? В том. что не нужно ILC_COLOR16, а нужно ILC_COLOR?

нет,  в том, что надо юзать ImageList_AddMasked для прозрачности битмапа

artsb, так, что ли?
Код

        bpl = 2 * bmp.bmWidth; /* bytes per line */
        src = (UCHAR*)lpbitmap;
        for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
            tmp = src;
            for (x = 0; x < bmp.bmWidth; x++) {
                dst[0] = tmp[0];
                dst[1] = tmp[1];

                dst += 2;
                tmp += 2;
            }
        }



Значит, сделал как писал, использовал 2 байта + ImageList_AddMasked. 
Получилось!!
Спасибо всем.

Это сообщение отредактировал(а) Alca - 21.1.2013, 13:34


--------------------
PM WWW ICQ Skype Jabber   Вверх
artsb
Дата 21.1.2013, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(Alca @  21.1.2013,  12:20 Найти цитируемый пост)
artsb, так, что ли?

Неа.
Судя по Википедии, может быть три варианта:
Код

11111111 11111111
|  ||  | |  ||  |
\  /\  / \  /\  /
 r   g    b   a


11111111 11111111
|   ||    ||   ||
\   /\   /  \  /|
  r    g     b  a


11111111 11111111
|   ||     ||   |
\   /\    /  \  /
  r    g       b  

Какой из них используется в Винде я не знаю. Нужно покопаться.

Добавлено через 1 минуту и 10 секунд
Или реализовать все и посмотреть, какой из них будет работать  smile 


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alca
Дата 21.1.2013, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



У меня так работает (16/32 bit):
Код

    if (16 >= wBitsPixel) {
        bpl = 4 * bmp.bmWidth; /* bytes per line */
        src = (UCHAR*)lpbitmap;
        for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
            tmp = src;
            for (x = 0; x < bmp.bmWidth; x++) {
                dst[0] = tmp[0];
                dst[1] = tmp[1];
                dst[2] = tmp[2];
                dst[3] = tmp[3];

                dst += 4;
                tmp += 4;
            }
        }
    } else {
        bpl = 4 * bmp.bmWidth; /* bytes per line */
        src = (UCHAR*)lpbitmap;
        for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
            tmp = src;
            for (x = 0; x < bmp.bmWidth; x++) {
                alpha = tmp[3];

                dst[0] = tmp[0] * alpha / 255;
                dst[1] = tmp[1] * alpha / 255;
                dst[2] = tmp[2] * alpha / 255;
                dst[3] = alpha;

                dst += 4;
                tmp += 4;
            }
        }
    }



--------------------
PM WWW ICQ Skype Jabber   Вверх
artsb
Дата 21.1.2013, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(Alca @  21.1.2013,  13:48 Найти цитируемый пост)
У меня так работает (16/32 bit):

Странно... Я себе это представлял несколько иначе (для первого случая):
Код

    union UColor16bit
    {
        unsigned short Color; // 16bit
        struct
        {
            unsigned char Hi;
            unsigned char Low;
        } Parts;
        struct
        {
            unsigned short r: 4;
            unsigned short g: 4;
            unsigned short b: 4;
            unsigned short a: 4;
        } ARGB;
    };

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    UColor16bit cColor;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            cColor.Color = 0;
            
            cColor.ARGB.r = tmp[0] & 0xF;
            cColor.ARGB.g = tmp[1] & 0xF;
            cColor.ARGB.b = tmp[2] & 0xF;
            cColor.ARGB.a = tmp[3] & 0xF;
            
            dst[0] = cColor.Parts.Hi;
            dst[1] = cColor.Parts.Low;
            
            dst += 2; // 16bit
            tmp += 4;
        }
    }


Это сообщение отредактировал(а) artsb - 21.1.2013, 14:40


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alca
Дата 21.1.2013, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Тестил на WinXP, Win2003 Server.
artsb, если честно, то я давно не кодил гуй на чистом WinAPI, 
может ты и правильно сдеалал


--------------------
PM WWW ICQ Skype Jabber   Вверх
artsb
Дата 21.1.2013, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 5
Всего: 64



Цитата(Alca @  21.1.2013,  14:31 Найти цитируемый пост)
Тестил на WinXP, Win2003 Server.
artsb, если честно, то я давно не кодил гуй на чистом WinAPI, 
может ты и правильно сдеалал 

Может быть smile Просто ваш рабочий код рознится с описанием с Вики smile Ну, раз работает... Хотя, я бы разобрался )


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Alca
Дата 21.1.2013, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Будет время - надо бы разобраться. 
Еще раз, спасибо.

Это сообщение отредактировал(а) Alca - 21.1.2013, 14:51


--------------------
PM WWW ICQ Skype Jabber   Вверх
Dem_max
Дата 23.1.2013, 06:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



А просто так не пробовал ???
Код

HICON hIcon = (HICON)LoadImage(hModule, szIcon, IMAGE_ICON, cx, cy, LR_CREATEDIBSECTION);
                                                           
himl = ImageList_Create(cx, cy, ILC_COLOR16 | ILC_MASK, 6, 0);
или так
himl = ImageList_Create(cx, cy, ILC_COLOR32 | ILC_MASK, 6, 0);
ImageList_AddIcon(himl, hIcon);

без всяких байтомодификаций ???

Это сообщение отредактировал(а) Dem_max - 23.1.2013, 06:47


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Alca
Дата 23.1.2013, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Dem_max, в этом проекте есть свои нюансы, каждый битмап храниться в массиве.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 4.2.2013, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Цитата

Код

    typedef union
    {
        unsigned short Color; // 16bit
        struct
        {
            unsigned char Hi;
            unsigned char Low;
        } Parts;
        struct
        {
            unsigned short r: 4;
            unsigned short g: 4;
            unsigned short b: 4;
            unsigned short a: 4;
        } ARGB;
    } UColor16bit;

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = (UCHAR*)lpbitmap;
    UColor16bit cColor;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            cColor.Color = 0;

            cColor.ARGB.r = tmp[0] & 0xF;
            cColor.ARGB.g = tmp[1] & 0xF;
            cColor.ARGB.b = tmp[2] & 0xF;
            cColor.ARGB.a = tmp[3] & 0xF;

            dst[0] = cColor.Parts.Hi;
            dst[1] = cColor.Parts.Low;

            dst += 2; // 16bit
            tmp += 4;
        }
    }


Не работает!!

Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  Pic.png 2,99 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 4.2.2013, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Цитата

Код

    bpl = 4 * bmp.bmWidth; /* bytes per line */
    src = lpbitmap;
    for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
        tmp = src;
        for (x = 0; x < bmp.bmWidth; x++) {
            if (wBitsPixel > 16) {
                alpha = tmp[3];

                dst[0] = tmp[0] * alpha / 255;
                dst[1] = tmp[1] * alpha / 255;
                dst[2] = tmp[2] * alpha / 255;
                dst[3] = alpha;
            } else {
                dst[0] = tmp[0];
                dst[1] = tmp[1];
                dst[2] = tmp[2];
                dst[3] = tmp[3];
            }

            dst += 4;
            tmp += 4;
        }
    }



Это сообщение отредактировал(а) Alca - 4.2.2013, 23:00

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  Pic2.png 3,83 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0968 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.