返回首页

简单的菜单|:简约的方法 - 显示图标{A}
{S0}简介
在CodeProject上的精彩文章,菜单上的图片处理要求的深刻理解,大量的自定义代码,并呈现完全依赖新类的应用程序。我们尝试了所有的用户输入的是与自然的工具,即嵌入到微软Visual Studio的资源编辑器生成一个简单的复制粘贴结构。
代码已建立与Visual Studio 2005和Visual C 6,并在Windows XP和Windows 2000测试。你需要建立你的MFC应用程序
首先,确保您的应用程序正常工作。然后,添加以下三个功能到你的CMainFrame类(或对话框,如果您的应用程序是基于对话框的):

    afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis);

    afx_msg void OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu);

    afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis);

           HMENU GetIconForItem(UINT itemID) const;

添加这些消息映射条目:{C}
BEGIN_MESSAGE_MAP(CMainFrame中,CFrameWnd中)和END_MESSAGE_MAP()之间。
最后,粘贴到您的CPP文件中的这四个功能:
HICON CMainFrame::GetIconForItem(UINT itemID) const

{

    HICON hIcon = (HICON)0;



    if (IS_INTRESOURCE(itemID))

    {    

        hIcon = (HICON)::LoadImage(::AfxGetResourceHandle(), 

                MAKEINTRESOURCE(itemID), IMAGE_ICON, 0, 0, 

                LR_DEFAULTCOLOR | LR_SHARED);

    }



    if (!hIcon)

    {

        CString sItem; // look for a named item in resources



        GetMenu()->GetMenuString(itemID, sItem, MF_BYCOMMAND);

        sItem.Replace(_T(' '), _T('_'));

        // cannot have resource items with space in name



        if (!sItem.IsEmpty())

            hIcon = (HICON)::LoadImage(::AfxGetResourceHandle(), sItem, 

                     IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_SHARED);

    }

    return hIcon;

}



void CMainFrame::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpdis)

{

    if ((lpdis==NULL)||(lpdis->CtlType != ODT_MENU))

    {

        CFrameWnd::OnDrawItem(nIDCtl, lpdis);

        return; //not for a menu

    }



    HICON hIcon = GetIconForItem(lpdis->itemID);

    if (hIcon)

    {

        ICONINFO iconinfo;

        ::GetIconInfo(hIcon, &iconinfo);



        BITMAP bitmap;

        ::GetObject(iconinfo.hbmColor, sizeof(bitmap), &bitmap);

        ::DeleteObject(iconinfo.hbmColor);

        ::DeleteObject(iconinfo.hbmMask);



        ::DrawIconEx(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, 

                     hIcon, bitmap.bmWidth, bitmap.bmHeight, 0, NULL, DI_NORMAL);

//      ::DestroyIcon(hIcon); // we use LR_SHARED instead

    }

}



void CMainFrame::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)

{

    AfxTrace(_T(__FUNCTION__) _T(": %#0x\n"), pMenu->GetSafeHmenu());

    CFrameWnd::OnInitMenuPopup(pMenu, nIndex, bSysMenu);



    if (bSysMenu)

    {

        pMenu = GetSystemMenu(FALSE);

    }

    MENUINFO mnfo;

    mnfo.cbSize = sizeof(mnfo);

    mnfo.fMask = MIM_STYLE;

    mnfo.dwStyle = MNS_CHECKORBMP | MNS_AUTODISMISS;

    pMenu->SetMenuInfo(&mnfo);



    MENUITEMINFO minfo;

    minfo.cbSize = sizeof(minfo);



    for (UINT pos=0; pos < pMenu->GetMenuItemCount(); pos++)

    {

        minfo.fMask = MIIM_FTYPE | MIIM_ID;

        pMenu->GetMenuItemInfo(pos, &minfo, TRUE);



        HICON hIcon = GetIconForItem(minfo.wID);



        if (hIcon && !(minfo.fType & MFT_OWNERDRAW))

        {

            AfxTrace(_T("replace for \"%s\" id=%u width=%d\n"), 

                    (LPCTSTR)sItem, (WORD)minfo.wID, 0); // size.cx);



            minfo.fMask = MIIM_FTYPE | MIIM_BITMAP;

            minfo.hbmpItem = HBMMENU_CALLBACK;

            minfo.fType = MFT_STRING;



            pMenu->SetMenuItemInfo(pos, &minfo, TRUE);

        }

        else

            AfxTrace(_T("keep for %s id=%u\n"), (LPCTSTR)sItem, (WORD)minfo.wID);

//        ::DestroyIcon(hIcon); // we use LR_SHARED instead

    }

}



void CMainFrame::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpmis)

{

    if ((lpmis==NULL)||(lpmis->CtlType != ODT_MENU))

    {

        CFrameWnd::OnMeasureItem(nIDCtl, lpmis); //not for a menu

        return;

    }



    lpmis->itemWidth = 16;

    lpmis->itemHeight = 16;



    CString sItem;

    GetMenu()->GetMenuString(lpmis->itemID, sItem, MF_BYCOMMAND);



    HICON hIcon = GetIconForItem(lpmis->itemID);



    if (hIcon)

    {

        ICONINFO iconinfo;

        ::GetIconInfo(hIcon, &iconinfo);



        BITMAP bitmap;

        ::GetObject(iconinfo.hbmColor, sizeof(bitmap), &bitmap);

        ::DeleteObject(iconinfo.hbmColor);

        ::DeleteObject(iconinfo.hbmMask);



        lpmis->itemWidth = bitmap.bmWidth;

        lpmis->itemHeight = bitmap.bmHeight;



        AfxTrace(_T(__FUNCTION__) _T(": %d \"%s\"%dx%d ==> %dx%d\n"), 

                (WORD)lpmis->itemID, (LPCTSTR)sItem, bitmap.bmWidth, 

                bitmap.bmHeight, lpmis->itemWidth, lpmis->itemHeight);

    }

}

现在,你可以编译您的应用程序,看到这一切都没有改变。为了你的截图上看到的一些菜单项,添加图像,您只需图标添加到您的资源。图标ID应该是菜单ID相同。这是所有。
它的图标呈现好听的责任。大小并不重要。一个良好的图标编辑器(我用的图标插件)可以创建任意大小和颜色的图标。
有时候,这是不够的。不幸的是,菜单项包含子菜单没有菜单的ID。或者至少,你可以不设置这样的资源编辑器的ID。对于这些情况,您可以添加一个图标,其名称对应的子菜单的名称。像这样:
ICONS                   ICON                    "res\\lock.ico"

...

IDR_MAINFRAME MENU 

BEGIN

    POPUP "&File"

    BEGIN

        POPUP "Icons"

该方法映射菜单图标的文字使用下划线(_)替换空格字符;此外,请注意,您可以使用的放大器;图标标识符的字符,但有一个陷阱:在Windows资源管理器将其识别为第一个这样的一个图标列表中,并用它来代表你的可执行文件。解决方法:设置标识符放大器;用来调用IDR_MAINFRAME的图标(一个字符)。一些披露的法宝
我们扫描,因为他们要显示菜单,并添加一个标志,该项目应自行绘制位图。如果资源文件为这个项目提供了一个图标,位图中提取图标。 WM_MEASUREITEM消息,只要求为位图的大小。
注意,所有的样式像变灰,默认情况下,等数据仍然可用。不幸的是,灰色的图标是在全彩显示项目时,突出显示(选择)。您将需要一个特殊的函数(在评论中发表的由B GA)来覆盖此行为。
我们设置菜单风格MNS_CHECKORBMP纯粹审美原因。但是,如果有些连接的图标,这些项目的检查,复选标记将覆盖自定义绘制的回调。另一方面,提出的方法可以很容易地推广到显示自定义丰富多彩的检查标志。关于菜单栏有些话
这里介绍的技术与菜单栏(即以上的客户区窗口,文件编辑查看帮助总是可见的一部分,这是)工作,但结果是小于完美(例如,下划线绘制在图像),并要求搞乱Windows提供的OnDrawItem函数的矩形。无论如何,附加代码(压缩演示)绘制一个图标,在菜单栏中。如果你有32位(XP风格)的图标和Win2K?
这可能听起来好笑,但直到最近,我遇到一个真彩色32位的图标显示在Windows 2000上的要求。在Windows XP中,所有你所要做的的是调用DrawIconEx(HDC,左,上,惠康,宽度,高度,0,NULL,则DI_NORMAL);不过,在Windows 2K,alpha通道是忽略这个API。如下片段,与旧版的Windows兼容。需要注意的是32位的图标是一个简单的的方式来表示带有alpha通道的位图。图标格式是没有办法仅限于预定义平方米大小​​,实际上是比32位的BMP格式支持。我个人使用Paint.NET"保险公司条例"插件生成等资源。
static inline unsigned int alphaBlend(const unsigned int bg, const unsigned int src)

{

    unsigned int    a = src >> 24;    // sourceColor alpha



    // If source pixel is transparent, just return the background

    if (0 == a) return bg;



    if (255 == a) return src;



    // alpha-blend the src and bg colors

    unsigned int rb = (((src & 0x00ff00ff) * a) + 

          ((bg & 0x00ff00ff) * (0xff - a))) & 0xff00ff00;

    unsigned int    g  = (((src & 0x0000ff00) * a) + 

          ((bg & 0x0000ff00) * (0xff - a))) & 0x00ff0000;



    return (src & 0xff000000) | ((rb | g) >> 8);

}



void MyDrawIcon(HDC hdc, int iconID, int left=0, int top=0, int width=0, int height=0)

{

    if (iconID <= 0)

        return;



    HICON hIcon = LoadIcon(iconID);



    if (!hIcon)

    {

#ifdef _DEBUG

        static bool once = true;

        if (once)

        {

            once = false;

            char str[100];

            HWND hwnd = WindowFromDC(hdc);

            if (GetDlgCtrlID(hwnd))

            {

                sprintf_s(str, "iconID=%d is unknown for control=%d", 

                          iconID, GetDlgCtrlID(hwnd));

                MessageBoxA(GetParent(hwnd), str, "Debug", MB_OK | MB_APPLMODAL);

            }

            else

            {

                sprintf_s(str, "iconID=%d is unknown for window=%#x", iconID, hwnd);

                MessageBoxA(hwnd, str, "Debug", MB_OK | MB_APPLMODAL);

            }

        }

#endif

        return;

    }



#if 1 // WIN2K

    ICONINFO iconInfo;

    GetIconInfo(hIcon, &iconInfo);

    if (iconInfo.hbmMask)

    {

        BITMAP bm;

        GetObject(iconInfo.hbmMask, sizeof(bm), &bm);

        DeleteBitmap(iconInfo.hbmMask);

    }



    if (!iconInfo.hbmColor)

    {

#ifdef _DEBUG

        static bool once = true;

        if (once)

        {

            once = false;

            char str[100];

            HWND hwnd = WindowFromDC(hdc);

            if (GetDlgCtrlID(hwnd))

            {

                sprintf_s(str, "iconInfo.hbmColor is NULL for control=%d", 

                          GetDlgCtrlID(hwnd));

                MessageBoxA(GetParent(hwnd), str, "Debug", MB_OK | MB_APPLMODAL);

            }

            else

            {

                sprintf_s(str, "iconInfo.hbmColorhbmColor is NULL for window=%#x", hwnd);

                MessageBoxA(hwnd, str, "Debug", MB_OK | MB_APPLMODAL);

            }

        }

#endif

        return;

    }



    BITMAP bm;

    GetObject(iconInfo.hbmColor, sizeof(bm), &bm);



    if (width == 0)

        width = bm.bmWidth;



    if (height == 0)

        height = bm.bmHeight;



    if (bm.bmBitsPixel != 32)

    {

#ifdef _DEBUG

        static bool once = true;

        if (once)

        {

            once = false;

            char str[100];

            HWND hwnd = WindowFromDC(hdc);

            if (GetDlgCtrlID(hwnd))

            {

                sprintf_s(str, "iconInfo.hbmColor Bits/Pixel=%d" + 

                          " is not correct for control=%d", 

                          bm.bmBitsPixel, GetDlgCtrlID(hwnd));

                MessageBoxA(GetParent(hwnd), str, "Debug", MB_OK | MB_APPLMODAL);

            }

            else

            {

                sprintf_s(str, "iconInfo.hbmColor Bits/Pixel=%d" + 

                          " is not correct for window=%#x", bm.bmBitsPixel, hwnd);

                MessageBoxA(hwnd, str, "Debug", MB_OK | MB_APPLMODAL);

            }

        }

        DeleteBitmap(iconInfo.hbmColor);

#endif

        return;

    }



    BITMAPINFO bmi = { sizeof(BITMAPINFOHEADER) };

    // get bitmap info

    GetDIBits(hdc, iconInfo.hbmColor, 0, bm.bmHeight, NULL, &bmi, DIB_RGB_COLORS);

    // prepare pixel buffer; note we use 32 bits per pixel



    LPDWORD iconBits = (LPDWORD)malloc(bmi.bmiHeader.biSizeImage);

    // get pixels

    GetDIBits(hdc, iconInfo.hbmColor, 0, bm.bmHeight, iconBits, &bmi, DIB_RGB_COLORS);



    // if width and height are specified, use these for destination bitmap

    bmi.bmiHeader.biWidth = width;

    bmi.bmiHeader.biHeight = height;



    HDC hdcMem = CreateCompatibleDC(hdc);

    LPDWORD pBitsDest = NULL;

    HBITMAP hBmpDest = CreateDIBSection(hdcMem, &bmi, DIB_RGB_COLORS, 

                                       (void **)&pBitsDest, NULL, 0);

    HBITMAP hOld = SelectBitmap(hdcMem, hBmpDest);



    // copy the background to memory DC; the pBitsDest buffer will reflect the change

    HWND hwnd = WindowFromDC(hdc);

    if (IsWindow(hwnd) && GetDlgCtrlID(hwnd)) // this is a dialog child

    {

        RECT rc;

        GetWindowRect(hwnd, &rc);

        ScreenToClient(GetParent(hwnd), (LPPOINT)&rc);

        HDC parentDC = GetDC(GetParent(hwnd));

        BitBlt(hdcMem, 0, 0, width, height, parentDC, rc.left+left, rc.top+top, SRCCOPY);

        ReleaseDC(GetParent(hwnd), parentDC);

    }

    else

    {

        BitBlt(hdcMem, 0, 0, width, height, hdc, left, top, SRCCOPY);

    }



    // tile the alpha mask image if the size does not fit

    for (int y=0, ys=0; y < height; y++, (++ys < bm.bmHeight) || (ys = 0))

    {

        for (int x=0, xs=0; x < width; x++, (++xs < bm.bmWidth) || (xs = 0))

        {

            *pBitsDest = alphaBlend(*pBitsDest, iconBits[xs + ys*bm.bmWidth]);

            pBitsDest++;

        }

    }



    // the bitmap has changed, select it and draw it

    SelectBitmap(hdcMem, hBmpDest);

    BitBlt(hdc, left, top, width, height, hdcMem, 0, 0, SRCCOPY);



    SelectBitmap(hdcMem, hOld);

    DeleteDC(hdcMem);

    DeleteBitmap(iconInfo.hbmColor);

    DeleteBitmap(hBmpDest);

    free(iconBits);



#else

    DrawIconEx(hdc, left, top, hIcon, width, height, 0, NULL, DI_NORMAL);

#endif

}
鸣谢和更新
感谢所有提意见,特别是Gernot弗里希,到B GA,并DarkWeaver5455和乔鹧鸪代码审查。请注意评论,其中B GA显示一个图标如何可以得出反映突出或停用状态。
2007年2月25日更新,解决资源泄漏,指出乔鹧鸪。演示项目的zip文件被更新,以反映在文章中公布的代码。在VC6编译,(这些变化都不会反映在文章正文)。
最新的更新(1/21/2008)显示,32位图标可以显示在Windows 2000。

回答

评论会员:游客 时间:2011/12/07
您的代码将在VC6编译了一些变化。除了明显的参数命名,一1。前GetIconForItem,添加codeprespanclass="code-keyword"typedef/spanULONGULONG_PTR;spanclass="code-preprocessor"#define/spanIS_INTRESOURCE(_r)(((ULONG_PTR)(_r)spanclass="code-digit"16/span)==spanclass="code-digit"0/span)/pre/code2。添加到stdafx.h的菜单信息代码进行编译。3。注释掉AfxTrace的。的份额。P/S不会在Windows7
。含羞草
评论会员:游客 时间:2011/12/07
文,这是杀了我。你需要在maiframe添加的代码量只是制定***菜单上的图标?必须有一个简单的方法来做到这一点。我们谈论的是位图...如何:CBitmap位图;bitmap.LoadBitmap(SOME_BITMAP);menu.ModifyMenu(commandID,MF_BYCOMMAND,commandID,位图);无需reinvinte轮每次添加一个功能..我的意思是,神垫imgsrc=http://www.orcode.com/upimg/2011_12_07_06_05_50_1.gif
亚历克斯科恩
评论会员:游客 时间:2011/12/07
垫,我全心全意地分享你的绝望。不幸的是,您的建议,不提供预期的功能。如果你决定尝试一下,你会看到一个菜单文本,而不是位图,而我的任务是将图标添加到现有的文本。此外,这一概念使资源文件内的任何图形操作,不接触,一旦你的应用程序代码粘贴三个MFC的处理程序
乔鹧鸪
评论会员:游客 时间:2011/12/07
您正在使用GetIconInfo的,但你不释放位图分配。
亚历克斯科恩
评论会员:游客 时间:2011/12/07
感谢​​,对你。我会尽快发布修复。亚历克斯科恩
DarkWeaver5455
评论会员:游客 时间:2011/12/07
只是出于兴趣,是什么最新更新有关?我没有WinMerge方便,所以我不能与我有什么最新版本...
亚历克斯科恩
评论会员:游客 时间:2011/12/07
1。我加你发现的bug修复。我更新的ZIP文件,以反映在文章中的代码的修复。新的ZIP在VC6编译,4。你绝对正确的,这说明应该已经公布,我现在修复了这个错误。,亚历克斯科恩
DarkWeaver5455
评论会员:游客 时间:2011/12/07
想说感谢,这篇文章是我的一个项目非常有用的我也应该指出的是,有几个拼写/格式化的文章的文本中的错误。我不肯定的。zip,我只是复制和粘贴。最值得注意的是posGetMenuItemCount();我猜的HTML过滤器是摆脱LT;PMENU\GT;,所以,我们没有看到任何有。此外,在GetIconForMenu你有pMenu-GetMenuString,虽然没有一个pMenu。我猜你的意思是GetMenu()-GetMenuString此外,感谢您添加的代码到BGA,完美,看上去很不错(虽然我真的不通知多大的差别时,该图标是'突出')-7时56分星期二20年2月,2007年修改
亚历克斯科恩
评论会员:游客 时间:2011/12/07
感谢​​很多校正。是的,在某些时候LT;,被吃掉了。你是绝对正确的GetMenu()-GetMenuString。我会尝试修复它......
B GA
评论会员:游客 时间:2011/12/07
突出我已经使用亮度增加10%(11/10)。如果你的图标已经亮(颜色通道接近255),你会不会注意到许多差异。如果你的图标不亮,你可以尝试增加20%(12/10),等,您也可以尝试使用对比,而不是亮度:codeprespanclass="code-keyword"double/spandContrast=spanclass="code-digit"1/span.spanclass="code-digit"1/span;spanclass="code-comment"///spanspanclass="code-comment"10%increase/spanspanclass="code-comment"///spanspanclass="code-comment"don'tforgettotrimiChannel(0..255)/spaniChannel=((spanclass="code-keyword"int/span)((((((spanclass="code-keyword"double/span)iChannel/spanclass="code-digit"255/span.spanclass="code-digit"0/span)-spanclass="code-digit"0/span.spanclass="code-digit"5/span)*dContrast)+spanclass="code-digit"0/span.spanclass="code-digit"5/span)*spanclass="code-digit"255/span));/pre/code在我的最终版本增加1个像素大小的图标(OnMeasureItem)在每个方向和DrawIconForItem(),我画(lpdisrcItem.left,lpdisrcItem.top),否则highlited图标(lpdisrcItem.left1,lpdisrcItem.top1)。
亚历克斯科恩
评论会员:游客 时间:2011/12/07
喜亚历克斯,能否总结一下,有什么变化呢?dan.g.imgsrc=http://www.orcode.com/upimg/2011_12_07_06_05_50_3.gifabstractspoon2_at_optusnet_dot_com_dot_au
B GA
评论会员:游客 时间:2011/12/07
主要的变化是腐败的语法突出显示{S2}此外,由于到BGA,我清理线minfo.fMask=MIIM_FTYPE|MIIM_BITMAP;
亚历克斯科恩
评论会员:游客 时间:2011/12/07
你有任何想法如何提高代码以显示禁用(变灰)禁用的菜单项的图标?
B GA
评论会员:游客 时间:2011/12/07
自动为我工作-看到的示范项目,甚至屏幕截图。因为它没有什么是预期的,我从来没有试图了解为什么和怎样......{S2}
亚历克斯科恩
评论会员:游客 时间:2011/12/07
我在XPSP2/VS2005的,它并非如此。我对您的演示项目(禁用的图标变灰)小图片菜单-我怎么能提供给您能否请你确认是真的,禁用的图标显示为禁用BTW,张贴在文章页面的代码不同于示范项目中的代码-MIIM_DATA仍然存在。
B GA
评论会员:游客 时间:2011/12/07
这是真的,我还没有续约的zip文件,但我会做到这一点,当我有更多的时间来清理任何可以清理。我没有得到我的电脑上安装了VS2005的现在。禁用(你实际上是讲关于MF_GRAYED,没有你?)示范项目的图标的技巧可能是一个MFC应用程序忽略在资源文件中显示为灰色的标签,但菜单项是否是在MFC消息映射的约束检查。让我们这样说:如果你把项目"是",它显示的项目之一变灰?
亚历克斯科恩
评论会员:游客 时间:2011/12/07
这是我做的。下载演示项目,在VS2005中建立,运行-所有的菜单都可以访问更新:我也建立在VS2002(XPSP1)和VS2003(XPSP2)。结果是相同的。P.S.演示项目包含。vcproj文件版本8.0(使VS2002和VS2003抱怨)。你用什么版本?
B GA
评论会员:游客 时间:2011/12/07
在序言中说,原计划是建立在VS2005和XP和​​2K的测试。我已经适应了这里我已经安装了VC6的(几个化妆品的变化),稍后我会后的固定ZIP文件。我看到变灰的菜单项的行为如下:灰色的图标看起来,除非该项目高亮显示。当鼠标滑过时,彩色图标显示。我们看到了同样的行为呢?如果没有,请告诉如何为您的子菜单中的图标的第四个项目。我也附加在VC6发布的​​EXE,以防万一。
亚历克斯科恩
评论会员:游客 时间:2011/12/07
我会在图标文件放置3张图片(积极,highlited和残疾人),并使用它们根据项目的状态。P.S.我VC6的EXE-它没有被禁用。如果你有兴趣在GIF/JPEG。给我发电子邮件,我将其附加到的答复。
B GA
评论会员:游客 时间:2011/12/07
禁用的图标(灰色绘制)可依靠的视频驱动程序。我同意,可实现最通用的控制,如果你生成一个单独的"禁用"图标,我想我wouldv'e了,如果我真的需要这种行为。32位的图标,我是一个很酷的半透明的绘图,但没有"面具",并不能自动转换成灰色。
亚历克斯科恩
评论会员:游客 时间:2011/12/07
,我从来没有听说过的Windowsico文件,没有一个掩码位图我创建的小功能,我用,而不是DrawIconEx。greyscalesgreyout项目和亮点图标的图标,如果它是突出​​。{BR​​}我张贴在下面,如果有人需要自动关闭功能。如果您选择的话,您可以更新您的演示项目。注:由于图标的大小是小,我用GetPixel()/SetPixel()和表现确定。对于大图标,直接位操作可能表现良好的必要。codeprespanclass="code-keyword"void/spanCMainFrame::DrawIconForItem(LPDRAWITEMSTRUCTlpdis)spanclass="code-keyword"const/span{HICONhIcon=GetIconForItem(lpdis-itemID);spanclass="code-keyword"if/span(!hIcon)spanclass="code-keyword"return/span; ICONINFOiconinfo;::GetIconInfo(hIcon,&iconinfo); BITMAPmask;::GetObject(iconinfo.hbmMask,spanclass="code-keyword"sizeof/span(mask),&mask); ::DrawIconEx(lpdis-hDC,lpdis-rcItem.left,lpdis-rcItem.top,hIcon,mask.bmWidth,mask.bmHeight,spanclass="code-digit"0/span,NULL,DI_NORMAL); spanclass="code-keyword"bool/spanbGrey=(lpdis-itemState&ODS_GRAYED?spanclass="code-keyword"true/span:spanclass="code-keyword"false/span);spanclass="code-keyword"bool/spanbHigh=(lpdis-itemState&ODS_SELECTED?spanclass="code-keyword"true/span:spanclass="code-keyword"false/span);spanclass="code-keyword"if/span(bGrey||bHigh){HDChDCMask=CreateCompatibleDC(lpdis-hDC);HBITMAPhOldMask=(HBITMAP)SelectObject(hDCMask,iconinfo.hbmMask);COLORREFcrMask,crIcon;BYTEbIcon,bIconR,bIconG,bIconB; spanclass="code-keyword"for/span(spanclass="code-keyword"int/spany=spanclass="code-digit"0/span;y<mask.bmHeight;y++){spanclass="code-keyword"for/span(spanclass="code-keyword"int/spanx=spanclass="code-digit"0/span;x<mask.bmWidth;x++){crMask=GetPixel(hDCMask,x,y);spanclass="code-keyword"if/span(crMask==spanclass="code-digit"0/span)spanclass="code-comment"///spanspanclass="code-comment"updateiconpixel/span{crIcon=GetPixel(lpdis-hDC,lpdis-rcItem.left+x,lpdis-rcItem.top+y);bIconR=(BYTE)((crIcon)&0xFF);bIconG=(BYTE)((crIconspanclass="code-digit"8/span)&0xFF);bIconB=(BYTE)((crIconspanclass="code-digit"16/span)&0xFF);spanclass="code-keyword"if/span(bGrey){spanclass="code-comment"///spanspanclass="code-comment"converttogreyscale/spanbIcon=(BYTE)((((WORD)bIconB+(WORD)bIconG*spanclass="code-digit"6/span+(WORD)bIconR*spanclass="code-digit"3/span)/spanclass="code-digit"10/span)&0xFF);spanclass="code-keyword"if/span(bIcon<spanclass="code-digit"64/span)spanclass="code-comment"///spanspanclass="code-comment"makeblacknessclosertogrey/spanbIcon=(spanclass="code-digit"64/span-((spanclass="code-digit"64/span-bIcon)*spanclass="code-digit"7/span/spanclass="code-digit"10/span));spanclass="code-keyword"else/spanspanclass="code-keyword"if/span(bIconspanclass="code-digit"192/span)spanclass="code-comment"///spanspanclass="code-comment"makewhitenessclosertogrey/spanbIcon=(spanclass="code-digit"192/span+((bIcon-spanclass="code-digit"192/span)*spanclass="code-digit"7/span/spanclass="code-digit"10/span));bIconR=bIconG=bIconB=bIcon;}spanclass="code-keyword"if/span(bHigh==spanclass="code-keyword"true/span){spanclass="code-comment"///spanspanclass="code-comment"highlight/spanbIconR=(BYTE)(((WORD)bIconR*spanclass="code-digit"11/span/spanclass="code-digit"10/span)0xFF?0xFF:((WORD)bIconR*spanclass="code-digit"11/span/spanclass="code-digit"10/span));bIconG=(BYTE)(((WORD)bIconG*spanclass="code-digit"11/span/spanclass="code-digit"10/span)0xFF?0xFF:((WORD)bIconG*spanclass="code-digit"11/span/spanclass="code-digit"10/span));bIconB=(BYTE)(((WORD)bIconB*spanclass="code-digit"11/span/spanclass="code-digit"10/span)0xFF?0xFF:((WORD)bIconB*spanclass="code-digit"11/span/spanclass="code-digit"10/span));}SetPixel(lpdis-hDC,lpdis-rcItem.left+x,lpdis-rcItem.top+y,RGB(bIconR,bIconG,bIconB));}}}SelectObject(hDCMask,hOldMask);DeleteDC(hDCMask);}}/pre/code
B GA
评论会员:游客 时间:2011/12/07
感谢您分享此功能。我认为您使用的技术maniplate图标颜色可能适合你的股票有图像,但不necesserily适合其他方案。GetPixel/SetPixel似乎给我一个合理的选择,特别是因为他们不使用的所有图标。回复:掩码位图-32位图标(XP风格),作为示例项目中包括的,有一个完整的8位Alpha通道determins部分每个像素的透明度。
Gunn317
评论会员:游客 时间:2011/12/07
我测试这个功能在XP图标(32位)和它工作得很好。由于工作是绘制图标后,就没有必要工作透明度。没有图标的位深度检查点-所有类型的图标功能正常工作。
B GA
评论会员:游客 时间:2011/12/07
看到你的代码转换成代码的图标突出或灰度(下同)。但我想知道......你有没有搞清楚如何使用的图标资源的3幅图像做同样的事情,就像你在这里提到?我已经正常,突出和灰度,我想使用的图标。我无法找出真正的问题是,如何做到的LoadImage()类型的事情,从第二或第三个索引形象的图标资源?如果你能提供什么,我将不胜感激。