Frage

EDIT: Ich habe eine Prämie angeboten, da ich bezweifle, dass ich sonst keine Antworten bekommen

.

In letzter Zeit ich habe mit Listviews arbeiten, und ich habe beschlossen, ein Symbol für jedes Element hinzuzufügen, der angibt, ob es Ein- oder Ausgang. Die Symbole hinzufügen in Ordnung, aber sie sind nicht transparent:

Beispiel für Symbol nicht transparent zu sein

Wie man sehen kann, sind die Symbole eindeutig nicht transparent. Ich bin zur Zeit so etwas wie diese Last auf die Symbole zu tun:

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

Ich habe mit den Flaggen versucht Messing für ImageList_Create & LoadIcon / LoadImage aber haben kein Glück gehabt und um ehrlich zu sein, habe ich die Ideen ausgehen.

Jede Hilfe wäre sehr geschätzt.

War es hilfreich?

Lösung

Als erstes, ImageList_ReplaceIcon kopiert das Symbol Daten beim Hinzufügen es zu einer Bildliste. So ist die HICON muss danach freigegeben werden.

Als nächstes sind Imagelists nativ Bitmaps, keine Symbole. Und die Art und Weise Sie Ihre Imagelist erstellen macht die Umwandlung von Symbol sehr zweideutig in Bitmap. ILC_COLOR32 impliziert die Abbildungsliste sollte als einen 32-Bit-DIB-Abschnitt erzeugt werden, die typischerweise Transparenzinformationen über einen eingebetteten Alphakanal enthalten. ILC_MASK bedeutet vielmehr, dass die internen Bitmaps sind DDB Bitmaps, mit den Transparenzinformationen als 1bpp Maske Bitmap gespeichert.

Die schnellste Lösung für Ihr Problem - nehmen Sie zwei Symbole:

  • verschmelzen sie in eine einzelne Bitmap-Ressource, das ist 32 pels der Breite und 16 hoch. Füllen Sie den Hintergrund mit einer Maske Farbe: -. Lila oder etwas
  • Erstellen Sie das Bitmap mit ILC_COLOR | ILC_MASK
  • die Bitmap Laden sicher zu verwenden LR_TRANSPARENT NICHT zu sein.
  • Fügen Sie die Bitmap mit ImageList_AddMasked in einem COLORREF vorbei, die die Maskenfarbe darstellt.

oder, für eine bessere visuelle Wirkung ...

  • exportieren Sie Ihre PNG-Daten als 32x16 32bpp Bitmap-Datei pre-multiplizierten Alphakanal-Daten enthält.
  • Erstellen Sie die Bildliste der ILC_COLOR32-Wert.
  • Loadimage () mit LR_CREATEDIBSECTION die Bitmap als 32bpp DIB-Abschnitt zu laden.
  • Fügen Sie das Bild mit ImageList_Add ()

(die letzte Option ist etwas schwierig, wenn die Anzahl von Werkzeugen, die 32-Bit unterstützt das Schreiben aus BMP-Dateien mit richtig multiplizierten Alpha-Kanälen vor eher niedrig).


Edited das folgende Codebeispiel hinzuzufügen. dieses in der Entwickler-Umgebung erstellt ein 4bpp Bitmap mit funktioniert einfach toll: -

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

Andere Tipps

Sie möchten Ihre Symbole, um eine Hintergrundfarbe haben, die nirgendwo sonst auf das Symbol verwendet wird, wie ein wirklich hässlich lila, und verwenden Sie dann Loadimage (..., LR_LOADTRANSPARENT); Die Flagge sagt bei 0,0 auf dem ersten Pixel aussehen und alles, was Farbe transparent machen.

Der Code sieht für mich in Ordnung, ich Loadimage immer statt LoadIcon verwenden, aber ich vermute, dass keine Rolle spielt. Haben Sie überprüft, dass die Symbole in der Tat zu tun haben transparente Bereiche und nicht selbst einen soliden Hintergrund haben?

Meine Anrufe Loadimage wie folgt aussehen:

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

Hier ... Erstellen Sie eine Abbildungsliste, wie vorgeschlagen, Ihre Symbole in eine Bitmap machen, 16 Pixel hoch, um 16 * n lang, wobei n = die Anzahl der Symbole ...

Stellen Sie die Hintergrundfarbe auf 255, 0, 255, wie Sie getan haben.

Dann laden Sie es, und es in die Bildliste hinzufügen, wie ich hier habe:

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

Natürlich ist dies wurde in MFC geschrieben, aber wie Sie wissen, es ist nur ein Wrapper für Win32 ...

Außerhalb dieser, Sie gehen zu einer Gewohnheit gehen, um die Kontrolle zeichnen, in dem Sie auf das Symbol ziehen über alles, was Hintergrund das Symbol sitzt auf sein geschieht. Es gibt wirklich keine Magie „transparent“ Farbe, die ich kenne, in jedem dieser Kontrollen.

Im Falle eines benutzerdefinierten ziehen, müssen Sie Code verwenden, wie folgt aus:

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

entscheidet Dieser Code, wo das Symbol zu zeichnen, und macht eine Momentaufnahme des Hintergrunds, schafft eine Maske für das Symbol, und dann zieht es über den Hintergrund, ihm einen voll transparenten Hintergrund zu geben ...

Hope, das etwas hilft. Wenn nicht, bitte erklären im Detail, was Sie versuchen geschehen zu lassen, und was Sie sehen, oder was Sie nicht zu sehen sind ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top