문제

편집하다: 나는 현상금을 제공했습니다. 그렇지 않으면 답을 얻을 것이라고 의심하기 때문입니다.

최근에 나는 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/LoadImage 그러나 운이 없었고 솔직히 말해서 아이디어가 부족합니다.

모든 도움은 대단히 감사 할 것입니다.

도움이 되었습니까?

해결책

먼저, ImageList_Replaceicon은 이미지 목록에 추가 할 때 아이콘 데이터를 복사합니다. 따라서 히콘은 나중에 공개해야합니다.

다음으로 Imagelists는 아이콘이 아닌 기본적으로 비트 맵입니다. 그리고 Imagelist를 만드는 방식은 아이콘을 비트 맵으로 변환하여 매우 모호합니다. ILC_COLOR32는 ImageList가 32 비트 DIB 섹션으로 생성되어야하며, 이는 일반적으로 임베디드 알파 채널을 통한 투명성 정보를 포함합니다. 대신 ILC_MASK는 내부 비트 맵이 DDB 비트 맵임을 암시하며 투명성 정보는 1BPP 마스크 비트 맵으로 저장됩니다.

문제에 대한 가장 빠른 해결책 - 두 아이콘을 가져 가십시오.

  • 그것들을 32 개의 픽스 x 16 높이의 단일 비트 맵 리소스로 병합하십시오. 마스크 색상으로 배경을 채우십시오 :- 보라색 또는 무언가.
  • ilc_color | ilc_mask를 사용하여 비트 맵을 만듭니다
  • lr_transparent를 사용하지 않도록 비트 맵을로드하십시오.
  • 마스크 색상을 나타내는 ColorRef에서 imageList_addmasked를 사용하여 비트 맵을 추가하십시오.

또는 더 나은 시각 효과를 위해 ...

  • PNG 데이터를 전년도 알파 채널 데이터를 포함하는 32x16 32bpp 비트 맵 파일로 내 보냅니다.
  • ILC_COLOR32 값을 사용하여 ImageList를 만듭니다.
  • Bitmap을 32bpp DIB 섹션으로로드하기 위해 lr_createdibsection이있는 loadImage ().
  • imageList_add ()를 사용하여 이미지 추가

(마지막 옵션은 Alpha 채널을 적절하게 곱한 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);

다른 팁

아이콘이 실제로 못생긴 자주색처럼 아이콘의 다른 곳에서는 사용되지 않는 배경색을 갖고로드 이민 (..., lr_loadtransparent)를 사용하려고합니다. 깃발은 0,0의 첫 번째 픽셀을보고 모든 것을 투명하게 만듭니다.

당신의 코드는 나에게 괜찮아 보인다. 나는 항상 loadicon 대신 loadimage를 사용하지만 그것이 중요하지 않다고 생각한다. 아이콘에 실제로 투명한 영역이 있고 그 자체가 탄탄한 배경을 가지고 있는지 확인 했습니까?

내 loadimage 호출은 다음과 같습니다.

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

여기 ... 제안 된 바와 같이 ImageList를 만들었습니다. 16*n 길이의 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;

이 코드는 아이콘을 그릴 위치를 결정하고 배경의 스냅 샷을 가져 와서 아이콘의 마스크를 생성 한 다음 배경 위로 그려서 완전히 투명한 배경을 제공합니다 ...

그것이 다소 도움이되기를 바랍니다. 그렇지 않다면, 당신이 무엇을하려고하는지, 무엇을보고 있는지, 무엇을보고 있지 않은지 더 자세히 설명하십시오 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top