Domanda

Quick background: I have a TreeView which I have created using Windows API calls in C++ (Visual Studio 2008, though that shouldn't make a difference):

hTreeview = CreateWindowEx(0, WC_TREEVIEW, L"My Treeview", WS_CHILD | WS_VISIBLE | TVS_INFOTIP | TVS_NOHSCROLL | TVS_SHOWSELALWAYS | TVS_EDITLABELS | TVS_SINGLEEXPAND, m_tx, m_ty, m_tw, m_th, hWindow, (HMENU)2, hInstance, NULL);

I have successfully assigned an ImageList to it using:

m_hImageList = ImageList_Create(cx, cy, ILC_COLOR24, n, n);
TreeView_SetImageList(hTreeview, m_hImageList, TVSIL_NORMAL);

where cx, cy, and n are all specified (in this case, 18, 18, and 5, respectively). This all works fine, as I can see because now there is space set aside next to my items for the image.

What I am trying to accomplish is to then copy a subsection of another bitmap (from a file). The code that I have tried (but does not work) is this:

HBITMAP hSkin = (HBITMAP)LoadImage(NULL, szPathBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
for (long i = 0; i < n; i++)
{
    HDC dcDest = CreateCompatibleDC(NULL);
    HBITMAP hIcon = CreateCompatibleBitmap(dcDest, cx, cy);
    HDC dcSrc = CreateCompatibleDC(NULL);
    SelectObject(dcSrc, hSkin);
    BitBlt(dcDest, 0, 0, cx, cy, dcSrc, x, y, SRCCOPY);
    *pIcon = ImageList_Add(m_hImageList, hIcon, NULL);
    DeleteObject(hIcon);
    DeleteDC(dcSrc);
    DeleteDC(dcDest);
}
DeleteObject(hSkin);

I have left out the error checking code for brevity, and it can be assumed that all of the listed variables have been set somewhere else in the program (forgive me for not providing a working source file, but this is a very large project and I have tried to include only the parts that are relevant).

All I get in the Treeview is black squares (which happens to be the background color of the Treeview), so I am assuming that something is going wrong with the last block of code--the one that loads the skin and tries to BitBlt a portion of it into a new bitmap to save to the ImageList. Can anyone either tell me what I'm doing wrong, or tell me a better way of accomplishing what I'm trying to do?

I am using C++ and the Windows API exclusively, no .NET, MFC, or Windows Form Designer.

Thanks in advance for your help, and if I've left anything out, I apologize; this is one of my first posts.

È stato utile?

Soluzione

There are a few problems with your code.

Firstly, when you create a new DC it starts out with a monochrome bitmap in it, so your CreateCompatibleBitmap call will also produce a monochrome one. Instead, you probably want to create the bitmap based on the window or screen DC.

Secondly, you never actually select the bitmap into dcDest, so nothing will be drawn into hIcon anyway.

Thirdly, ImageList_Add will fail if the bitmap is currently selected into a device context, so you have to deselect hIcon from dcDest before you add the icon to the image list.

Lastly, you are also neglecting to save the original bitmaps and restore them, so this will also cause a GDI leak.

Try something like this:

HDC hdcWindow = GetDC(hWnd);
HDC dcDest = CreateCompatibleDC(hDCWindow);
HBITMAP hIcon = CreateCompatibleBitmap(hDCWindow, cx, cy);
HDC dcSrc = CreateCompatibleDC(NULL);

HGDIOBJ hOldSourceBmp = SelectObject(dcSrc, hSkin);
HGDIOBJ hOldDestBmp = SelectObject(dcDest, hIcon);

BitBlt(dcDest, 0, 0, cx, cy, dcSrc, x, y, SRCCOPY);

SelectObject(dcDest, hOldDestBmp);
SelectObject(dcSrc, hOldSourceBmp);

*pIcon = ImageList_Add(m_hImageList, hIcon, NULL);

DeleteObject(hIcon);
DeleteDC(dcSrc);
DeleteDC(dcDest);
ReleaseDC(hWnd, hDCWindow);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top