让alpha混合与CImageList一起使用

时间:2016-10-17 23:40:42

标签: c++ windows imagelist wtl

我遇到的其他一些与此非常相似的问题:

  1. Is it possible to create a CImageList with alpha blending transparency?
  2. Transparent images in ImageLists for ListViews
  3. ImageList Transparency on Listviews?
  4. 我正在使用WTL9.0。我有一个框架窗口,其CTreeViewCtrlEx作为其子项。我正在使用SHGetFileInfo()来获取我想在树中使用的图标,但它们显示为黑色背景。这是一个完整的样本。

    #define WINVER        0x0601 // Windows 7
    #define _WIN32_WINNT  0x0601 // Windows 7
    
    #include <atlbase.h>      
    #include <atlapp.h>
    
    CAppModule g_AppModule; // WTL version of CComModule
    
    #include <atlwin.h>
    #include <atlframe.h>
    #include <atlcrack.h>
    #include <atlctrls.h>
    
    class MainWnd : public CFrameWindowImpl<MainWnd>
    {
      private:
        typedef MainWnd                    ThisClass;
        typedef CFrameWindowImpl<MainWnd>  BaseClass;
    
        static const DWORD TREE_STYLE = TVS_HASLINES | TVS_LINESATROOT | 
                                        TVS_HASBUTTONS | WS_CHILD | WS_VISIBLE;
    
        CTreeViewCtrlEx m_Tree;
        CImageList      m_ImgList;
    
      public:
        BEGIN_MSG_MAP(ThisClass)
          MSG_WM_CREATE(OnCreate)
          MSG_WM_DESTROY(OnDestroy)
          CHAIN_MSG_MAP(BaseClass)
        END_MSG_MAP()
    
        LRESULT OnCreate(CREATESTRUCT* pCreateStruct)
        {
          // Create the tree control
          LPCTSTR TREE_CLASS = CTreeViewCtrlEx::GetWndClassName();
          m_Tree.Create(*this, rcDefault, TREE_CLASS, TREE_STYLE);
          m_hWndClient = m_Tree;
    
          // Create the image list
          m_ImgList.Create(32, 32, ILC_COLOR32, 1, 1);
    
          SHFILEINFO sFileInfo = { 0 };
          const UINT FLAGS = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
          LPCTSTR PATH = _T("C:\\Windows");
    
          // Get the directory icon
          if (0 != ::SHGetFileInfo(PATH, FILE_ATTRIBUTE_DIRECTORY, &sFileInfo,
            sizeof(SHFILEINFO), FLAGS))
          {
            CIcon dirIcon(sFileInfo.hIcon);
            m_ImgList.AddIcon(dirIcon);
          }
    
          m_Tree.SetImageList(m_ImgList);
    
          // Insert three items into the tree
          CTreeItem rootItem = 
            m_Tree.InsertItem(_T("Root"), 0, 0, TVI_ROOT, TVI_LAST);
          m_Tree.InsertItem(_T("Sub1"), 0, 0, rootItem, TVI_LAST);
          m_Tree.InsertItem(_T("Sub2"), 0, 0, rootItem, TVI_LAST);
          m_Tree.Expand(rootItem);
    
          SetMsgHandled(false);
          return 0;
        }
    
        void OnDestroy()
        {
          if (m_Tree.IsWindow())
            m_Tree.DestroyWindow();
    
          m_ImgList.Destroy();
    
          SetMsgHandled(false);
        }
    };
    
    int __stdcall WinMain
    (
      HINSTANCE hInstance,
      HINSTANCE /*hPrevInstance*/,
      LPTSTR    /*wzCmdLine*/,
      int       nCmdShow
    )
    {
      g_AppModule.Init(nullptr, hInstance);
    
      MainWnd mainWindow;
      MSG msg = { 0 };
    
      if (nullptr == mainWindow.CreateEx())
        return 1;
    
      mainWindow.ShowWindow(nCmdShow);
      mainWindow.UpdateWindow();
    
      while (0 < ::GetMessage(&msg, nullptr, 0, 0))
      {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
      }
    
      g_AppModule.Term();
    
      return 0;
    }
    

    上面的第三个链接似乎表明我需要从图标中获取位图,复制它然后将其添加到图像列表中。

    然而,查看this project的代码意味着您应该能够简单地使用图标本身。如果你深入了解提供的类,只需使用图标句柄将其添加到列表中。这种比较的问题是它在C#中,事情可能会有所不同。

    This MSDN article表示支持32位alpha混合图标,但我还没有让它们工作。

    我已获取所提供代码中加载的图标的位图并查看像素数据,图像 包含Alpha通道以及列为32位。

    如果有人知道如何让它发挥作用,请你赐教我?

    编辑:以下是我发布的代码的图片。 TreeView with 32x32 icons

1 个答案:

答案 0 :(得分:4)

代码没问题,但Windows没有被告知正在使用的公共控件的版本。

您必须启用Visual Style。您可以在项目清单中执行此操作,或者至少在* .cpp文件中包含以下行:

#pragma comment(linker,"/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

请注意,此#pragma指令是特定于Visual Studio的,请将manifest与其他编译器一起使用。

此外,您可以添加对Windows主题的支持:

#include <UxTheme.h>
#pragma comment( lib, "UxTheme.lib" )
...    
SetWindowTheme(tree.m_hWnd, L"Explorer", NULL);

结果:

enter image description here