Treeview меняет цвет изображения элемента - PullRequest
0 голосов
/ 23 ноября 2018

Итак, я пытался добавить изображения к своим элементам общего управления WinAPI TreeView.Однако я столкнулся с чем-то, что действительно беспокоило меня, и я понятия не имею, почему это происходит.По какой-то причине изображение в TreeView имеет другой цвет, чем фактическое изображение.Я сделал скриншот созданной мной тестовой программы, которая рисует файл изображения BMP вместе с его аналогом TreeView.(Это точное одно и то же изображение, но оба рисунка дают разные результаты).

Window Screenshot

Как видно на рисункеслева это то, что должно выглядеть, а изображение справа - то, что рисует TreeView.Это именно так работает TreeView или что-то?Или в моем коде что-то не так?Было бы очень признательно, если бы кто-нибудь мог указать на это, потому что из личного вкуса изображение TreeView выглядит визуально отвратительно, и я бы хотел, чтобы элемент управления TreeView правильно рисовал мое изображение: P

Ниже приведен код, которым я являюсьиспользуя для создания Treeview:

    //Load image from relative file path
    g_hBmp = LoadImage(GetModuleHandle(NULL), "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);

    //Create Treeview
    HWND treeview = CreateWindowEx(0, WC_TREEVIEW, NULL,
        WS_VISIBLE | WS_CHILD | TVS_FULLROWSELECT,
        250, 100, 500, 300,
    hwnd, NULL, GetModuleHandle(NULL), NULL);

    //Add single treeview item
    TVITEM tvi = {0};
    TVINSERTSTRUCT tvins = {0};

    HIMAGELIST himl = NULL;
    himl = ImageList_Create(90, 90, 0, 1, 0);
    int image = ImageList_Add(himl, g_hBmp, NULL);

    SendMessage(treeview, TVM_SETIMAGELIST, (WPARAM) TVSIL_NORMAL, (LPARAM) himl);

    tvi.mask = TVIF_TEXT | TVIF_IMAGE;

    //Set Text
    tvi.pszText = "Some Item";
    tvi.cchTextMax = sizeof("Some Item") - 1;
    tvi.iImage = image;

    tvins.item = tvi;
    tvins.hInsertAfter = TVI_FIRST;
    SendMessage(treeview, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT) &tvins);

А вот мой весь код на случай, если вы хотите скопировать его:

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

HBITMAP g_hBmp = NULL;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {

        case WM_CREATE: {

            //Load Image
            g_hBmp = LoadImage(GetModuleHandle(NULL), "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);

            //Create Treeview
            HWND treeview = CreateWindowEx(0, WC_TREEVIEW, NULL,
                WS_VISIBLE | WS_CHILD | TVS_FULLROWSELECT,
                250, 100, 500, 300,
            hwnd, NULL, GetModuleHandle(NULL), NULL);

            //Add single treeview item
            TVITEM tvi = {0};
            TVINSERTSTRUCT tvins = {0};

            HIMAGELIST himl = NULL;
            himl = ImageList_Create(90, 90, 0, 1, 0);
            int image = ImageList_Add(himl, g_hBmp, NULL);

            SendMessage(treeview, TVM_SETIMAGELIST, (WPARAM) TVSIL_NORMAL, (LPARAM) himl);

            tvi.mask = TVIF_TEXT | TVIF_IMAGE;

            //Set Text
            tvi.pszText = "Some Item";
            tvi.cchTextMax = sizeof("Some Item") - 1;
            tvi.iImage = image;

            tvins.item = tvi;
            tvins.hInsertAfter = TVI_FIRST;
            SendMessage(treeview, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT) &tvins);

            break;

        }
        case WM_PAINT: {

            PAINTSTRUCT ps = {0};

            //Setup
            HDC hdc = BeginPaint(hwnd, &ps);
            HDC hdcPaint = CreateCompatibleDC(hdc);

            HBITMAP hBmpOld = (HBITMAP) SelectObject(hdcPaint, g_hBmp);

            //Painting
            BitBlt(hdc, 100, 100, 90, 90, hdcPaint, 0, 0, SRCCOPY);

            //Cleanup
            SelectObject(hdcPaint, hBmpOld);
            DeleteDC(hdcPaint);

            EndPaint(hwnd, &ps);
            break;

        }
        case WM_DESTROY: {

            DeleteObject(g_hBmp);
            PostQuitMessage(0);
            break;

        }
        default: return DefWindowProc(hwnd, msg, wParam, lParam);

    }

    return 0;

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {

    InitCommonControls();

    HWND hwnd = NULL;
    WNDCLASSEX wc = {0};

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "Parent Window";
    wc.style = CS_VREDRAW | CS_HREDRAW;

    RegisterClassEx(&wc);

    hwnd = CreateWindowEx(0, wc.lpszClassName, "Render Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 1000, 1000 / 16 * 9,
    NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, nShowCmd);
    UpdateWindow(hwnd);

    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0) > 0) {

        TranslateMessage(&msg);
        DispatchMessage(&msg);

    }

    return msg.wParam;

}

1 Ответ

0 голосов
/ 03 декабря 2018

Как упомянуто выше 'Swordfish', мне не хватало правильного флага при вызове функции ImageList_Create().Как вы можете видеть в моем вызове ImageList_Create(90, 90, 0, 1, 0);, я указываю '0' в качестве третьего параметра (который представляет Флаг создания списка изображений ).Как указано в документации, флаг ILC_COLOR имеет значение ноль;когда этот флаг установлен, он использует «поведение по умолчанию», которое часто равно ILC_COLOR4 (т.е. 4 бита на канал).

Чтобы исправить это, все, что мне нужно было сделать, это просто вызвать функцию, используя флаг ILC_COLOR24 , указывающий, что мои изображения имеют 24-битную глубину.

ImageList_Create(90, 90, ILC_COLOR24, 1, 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...