所以我一直在尝试将图像添加到我的 WinAPI TreeView 公共(public)控件项中。然而,我遇到了一些真正困扰我的事情,我不知道为什么会这样。由于某种原因,TreeView 中的图像与实际位图中的颜色不同。我截取了我制作的测试程序的屏幕截图,该程序绘制 BMP 图像文件及其对应的 TreeView 文件。 (这是完全相同的图像,但两张图产生不同的结果)。
如您所见,左边的图像是它应该看起来的样子,右边的图像是 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;
}
最佳答案
正如“Swordfish”在上面提到的,我缺少的是调用 ImageList_Create()
函数时的正确标志。正如您在调用 ImageList_Create(90, 90, 0, 1, 0);
时看到的那样,我将“0”指定为第三个参数(代表 Image List Creation Flag )。如文档中所述,ILC_COLOR 标志的值为零;设置此标志后,它使用通常为 ILC_COLOR4 的“默认行为”(即每个 channel 4 位)。
要解决此问题,我需要做的就是使用 ILC_COLOR24 标志调用该函数,表明我的图像具有 24 位深度。
ImageList_Create(90, 90, ILC_COLOR24, 1, 0);
关于c - TreeView 更改项目图像的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53440960/