1

簡単な背景: C++ で Windows API 呼び出しを使用して作成した TreeView があります (Visual Studio 2008 でも違いはありません)。

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);

以下を使用して、ImageList を正常に割り当てました。

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

ここでcx、 、cy、およびnはすべて指定されています (この場合は、それぞれ 18、18、および 5)。画像用にアイテムの横にスペースが確保されているため、これで問題なく動作します。

私が達成しようとしているのは、(ファイルから) 別のビットマップのサブセクションをコピーすることです。私が試した(しかし動作しない)コードは次のとおりです。

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);

簡潔にするためにエラー チェック コードを省略しました。一覧にあるすべての変数がプログラム内の別の場所に設定されていると想定できます (動作するソース ファイルを提供していないことをお許しください。ただし、これは非常に大規模なプロジェクトであり、関連する部分のみを含めようとしました)。

Treeview に表示されるのは黒い四角 (Treeview の背景色) だけなので、コードの最後のブロック (スキンをロードして BitBlt を試行するブロック) で何か問題が発生していると想定しています。その一部を新しいビットマップに変換して、ImageList に保存します。誰かが私が間違っていることを教えてくれますか、それとも私がやろうとしていることを達成するためのより良い方法を教えてくれますか?

私は C++ と Windows API のみを使用しており、.NET、MFC、または Windows フォーム デザイナーは使用していません。

あらかじめご協力いただきありがとうございます。省略している部分がありましたら、お詫び申し上げます。これは私の最初の投稿の 1 つです。

4

1 に答える 1

1

コードにはいくつかの問題があります。

まず、新しい DC を作成すると、モノクロのビットマップで開始されるため、CreateCompatibleBitmap呼び出しでもモノクロのビットマップが生成されます。代わりに、ウィンドウまたはスクリーン DC に基づいてビットマップを作成することをお勧めします。

第 2 に、ビットマップを実際に に選択することはないdcDestため、何も描画されませhIconん。

第 3 に、ImageList_Add現在ビットマップがデバイス コンテキストで選択されている場合は失敗するため、アイコンをイメージ リストに追加する前に選択を解除hIconする必要があります。dcDest

最後に、元のビットマップの保存と復元も怠っているため、これも GDI リークの原因となります。

次のようなことを試してください:

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);
于 2013-06-21T03:34:18.440 に答える