2009-03-10 11 views
3

編集:私は賞金を申し出ましたが、それ以外の方法で回答が得られるかどうかは疑問です。ImageListリストビューの透明度?

最近私はlistviewsで作業していましたが、入力か出力かを示す各項目に対してアイコンを追加することにしました。アイコンは細かい追加し、彼らは透明ではないです:

Example of icon not being transparent

アイコンが明確に透明でない、見ることができるように。私は現在、この負荷のようなアイコンをやってる:

hImageList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 2); 
    if (hImageList != NULL) 
    { 
    iIN = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(101))); 
    iOUT = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(102))); 
    } 

私はImageList_Create & LoadIcon/​​のためのフラグをいじって試してみたが、私はアイデアが不足してきた運を持っていなかったと正直に言うと。

ご協力いただければ幸いです。

+0

あなたは、私は人々があなたのコードをテストしているいくつかのコメントを参照してください..私はこの分野で多くの仕事をして以来、それを見てみたいです... – LarryF

+0

http: //stackoverflow.com/questions/6893351/transparent-images-in-imagelists-for-listviews/スレッド。 Olexiy –

答えて

11

まずアップ、ImageList_ReplaceIconコピーアイコンデータイメージリストに追加する:

マイLoadImageの呼び出しは次のようになり。だから、HICONはその後にリリースする必要があります。

次に、imagelistsはアイコンではなくネイティブのビットマップです。そしてあなたのimagelistを作成している方法は、アイコンからビットマップへの変換を非常にあいまいにします。 ILC_COLOR32は、イメージリストが32ビットのdibセクションとして作成されるべきであることを意味します。このセクションには、一般に、埋め込まれたアルファチャンネルを介した透明性情報が含まれます。 ILC_MASKは、内部ビットマップがDDBビットマップであり、透過情報が1bppマスクビットマップとして格納されていることを意味します。

あなたの問題への解決策最速 - 取るあなたの2つのアイコン:

  • が広い高16で32のペルthatsの単一ビットマップリソースにそれらをマージします。背景をマスクの色で塗りつぶす: - 紫色か何か。
  • ILC_COLOR | ILC_MASKを使用してビットマップを作成する
  • ビットマップをロードして、LR_TRANSPARENTを使用しないようにしてください。
  • マスクカラーを表すCOLORREFで渡すImageList_AddMaskedを使用してビットマップを追加します。

OR、より良い視覚効果のために...

  • はプリマルチアルファチャンネルデータを含む32×16 32bppのビットマップファイルとしてPNGデータをエクスポートします。
  • ILC_COLOR32値を使用してイメージリストを作成します。
  • LoadImage()でLR_CREATEDIBSECTIONを指定すると、ビットマップを32bppのdibセクションとしてロードできます。
  • はImageList_Addを使用した画像()

(最後のオプションは、一種のトリッキー適切に逓倍アルファチャンネルを事前に32ビットのBMPファイルを書き出すサポートするツールの数などでかなり低い)を追加します。


次のコードサンプルを追加するように編集しました。ただ偉大なデベロッパー環境で作成したところ4bppビットマップを作品の使用: -

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

私は今日の最初のオプションを試してみましたが、私は同じ問題がありました。あなたのポストを読んだ後、私は第2の方法を試しました、そして、それは全く違いをもたらしませんでした。これを見てください:http://pastebin.com/f5617ac8a – Irwin

+0

ILC \ _MASK | ILC \ _COLORを指定すると、どのようにビットマップをロードしていますか?おそらくDIBSECTIONフラグを省略して、DDBサーフェスへのビットマップのロードがロスであることに注意してください。ファイルの理想的なRGB値を表すCOLORREFはDDBのペルと一致できません。純粋な色を使用してください。 –

+0

... 2番目のオプションについてコメントを完全に無視しました。また、最初のオプションのLR_CREATEDIBSECTIONフラグを省略しました。私のマスクの色はピンク(RGB(255、0、255))でしたので、一致するものはありませんでした。 – Irwin

0

あなたのアイコンに、実際には醜い紫色のような、アイコンのどこにも使用されていない背景色を設定し、LoadImage(...、LR_LOADTRANSPARENT)を使用します。フラグは0,0の最初のピクセルを見て、その色のすべてを透明にします。

+1

私はすでにこれを試しています(最初のピクセルはRGB(255、0、255))。ドキュメントを引用しています.LR_LOADTRANSPARENTはイメージを透過的に読み込みません。すべての背景ピクセルがCOLOR_WINDOWに変更されたため、透明にしか見えない不透明なイメージリストが作成されます。 – Irwin

+0

ああ、それは理にかなっています。愚かなWindowsと透明なアイコン。 –

0

コードは私にとってはうまく見えますが、私はいつもLoadIconの代わりにLoadImageを使用していますが、問題ではないと思われます。あなたはアイコンが実際に透明な領域を持っていることを確認しましたが、それ自体は堅実な背景を持っていませんか?

HICON hIcon = (HICON)LoadImage(hinstResources,MAKEINTRESOURCE(IDI_ICON),IMAGE_ICON,16,16,LR_DEFAULTCOLOR); 
+0

私の元の記事で述べたように、私は既にLoadIconとLoadImageを使いこなしています。私はLR_DEFAULTCOLORフラグだけを使ってみましたが、違いはありませんでした。ああ、はい、私のアイコンは透明です:http://img12.imageshack.us/img12/6117/reseditxpirc776.png – Irwin

0

をここに... 16個のピクセル高、示唆されているように、イメージリストを作成し、ビットマップにあなたのアイコンを作る、nは長い16 *により、ここでn =アイコンの数...

背景色を255、0、255に設定します。

はその後、それをロードして、私はここに行ったようにイメージリストに追加します。もちろん

m_ImageList.Create(16, 16, ILC_COLOR16 | ILC_MASK, 7, 1); 
CBitmap bm; 
bm.LoadBitmap(IDB_SUPERTREEICONS); 
m_ImageList.Add(&bm, RGB(255, 0, 255)); 
GetTreeCtrl().SetImageList(&m_ImageList, TVSIL_NORMAL); 

、これはMFCで書かれていたが、あなたが知っているように、それは、Win32への単なるラッパーです。..

外では、カスタム描画コントロールに移動する必要があります。カスタム描画コントロールに移動する必要があります。このコントロールでは、アイコンの背景にアイコンが描画されます。私が知っている魔法の "透明な"色は、これらのコントロールのいずれにも本当にありません。

カスタムドローの場合は、次のようなコードを使用する必要があります。

#define TRANSPARENT_COLOR (255,0,255) 

UINT iBitmap = IDB_ICON_UP 
CDC *dc = GetDC(); 
int x = 0, y = 0; 

    CDC *pDisplayMemDC = new CDC; 
    CDC *pMaskDC = new CDC; 
    CDC *pMemDC = new CDC; 
    CBitmap *pBitmap = new CBitmap; 
    CBitmap *pMaskBitmap = new CBitmap; 
    CBitmap *pMemBitmap = new CBitmap; 
    int cxLogo, cyLogo; 
    BITMAP bm; 

    pBitmap->LoadBitmap(iBitmap); 
    pDisplayMemDC->CreateCompatibleDC(dc); 
    CBitmap *pOldBitmap = (CBitmap *)pDisplayMemDC->SelectObject(pBitmap); 

    pBitmap->GetObject(sizeof(bm), &bm); 
    cxLogo = bm.bmWidth; 
    cyLogo = bm.bmHeight; 

    pMaskBitmap->CreateBitmap(cxLogo, cyLogo, 1, 1, NULL); 
    pMaskDC->CreateCompatibleDC(dc); 
    CBitmap *pOldMask = (CBitmap *)pMaskDC->SelectObject(pMaskBitmap); 
    COLORREF oldBkColor = pDisplayMemDC->SetBkColor(TRANSPARENT_COLOR); 
    pMaskDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCCOPY); 

    pMemBitmap->CreateCompatibleBitmap(dc, cxLogo, cyLogo); 
    pMemDC->CreateCompatibleDC(dc); 
    CBitmap *pOldMem = (CBitmap *)pMemDC->SelectObject(pMemBitmap); 

    pMemDC->BitBlt(0, 0, cxLogo, cyLogo, dc,   x, y, SRCCOPY); 
    pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCINVERT); 
    pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pMaskDC,  0, 0, SRCAND); 
    pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCINVERT); 
     dc->BitBlt(x, y, cxLogo, cyLogo, pMemDC,  0, 0, SRCCOPY); 

    delete pMemDC->SelectObject(pOldMem); 
    delete pMemDC; 

    delete pMaskDC->SelectObject(pOldMask); 
    delete pMaskDC; 

    delete pDisplayMemDC->SelectObject(pOldBitmap); 
    delete pDisplayMemDC; 

このコードは、アイコンを描画することを決定し、背景のスナップショットを取り、マスクを作成し、アイコンをクリックし、それを背景に描画して、完全に透明な背景を与えます。

多少助けてくれることを望みます。そうでない場合は、何をしようとしているのか、何を見ているのか、または見ていないものをさらに詳しく説明してください...