如何从ARGB计算Windows颜色

3

有人能告诉我如何从ARGB计算出相应的Windows颜色吗?我知道有一个ColorTranslator.ToWin32()可以进行计算,但是具体是怎么做的呢?

另外,OLE颜色和Windows(win32)颜色之间有什么区别?

JD。

2个回答

3
使用IL反编译器(如Reflector),您可以获取ColorTranslator.ToWin32()代码。请注意,ToWin32颜色不使用alpha值。
public static int ToWin32(Color c)
{
    return ((c.R | (c.G << 8)) | (c.B << 0x10));
}

ColorTranslator.ToOle(...)用于测试颜色是否是标准系统颜色,否则将使用ToWin32转换:

public static int ToOle(Color c)
{
    if (c.IsKnownColor)
    {
        switch (c.ToKnownColor())
        {
            case KnownColor.ActiveBorder:
                return -2147483638;

            case KnownColor.ActiveCaption:
                return -2147483646;

            case KnownColor.ActiveCaptionText:
                return -2147483639;

            case KnownColor.AppWorkspace:
                return -2147483636;

            case KnownColor.Control:
                return -2147483633;

            case KnownColor.ControlDark:
                return -2147483632;

            case KnownColor.ControlDarkDark:
                return -2147483627;

            case KnownColor.ControlLight:
                return -2147483626;

            case KnownColor.ControlLightLight:
                return -2147483628;

            case KnownColor.ControlText:
                return -2147483630;

            case KnownColor.Desktop:
                return -2147483647;

            case KnownColor.GrayText:
                return -2147483631;

            case KnownColor.Highlight:
                return -2147483635;

            case KnownColor.HighlightText:
                return -2147483634;

            case KnownColor.HotTrack:
                return -2147483635;

            case KnownColor.InactiveBorder:
                return -2147483637;

            case KnownColor.InactiveCaption:
                return -2147483645;

            case KnownColor.InactiveCaptionText:
                return -2147483629;

            case KnownColor.Info:
                return -2147483624;

            case KnownColor.InfoText:
                return -2147483625;

            case KnownColor.Menu:
                return -2147483644;

            case KnownColor.MenuText:
                return -2147483641;

            case KnownColor.ScrollBar:
                return -2147483648;

            case KnownColor.Window:
                return -2147483643;

            case KnownColor.WindowFrame:
                return -2147483642;

            case KnownColor.WindowText:
                return -2147483640;

            case KnownColor.ButtonFace:
                return -2147483633;

            case KnownColor.ButtonHighlight:
                return -2147483628;

            case KnownColor.ButtonShadow:
                return -2147483632;

            case KnownColor.GradientActiveCaption:
                return -2147483621;

            case KnownColor.GradientInactiveCaption:
                return -2147483620;

            case KnownColor.MenuBar:
                return -2147483618;

            case KnownColor.MenuHighlight:
                return -2147483619;
        }
    }
    return ToWin32(c);
}

这意味着,如果你声明一个Color color = SystemColors.ControlText,ColorTranslator.ToOle(color)将返回-2147483630。但是,如果你设置颜色为自定义的ARGB颜色,则ColorTranslator.ToOle将返回标准的ToWin32()值。

2

.NET中的颜色对象包括一个alpha通道(即透明度水平),而Win32颜色仅为RGB。因此,要在两者之间进行转换,您需要像以下这样的内容:

    static public int ConvertColourToWindowsRGB(Color dotNetColour)
    {
        int winRGB = 0;

        // windows rgb values have byte order 0x00BBGGRR
        winRGB |= (int)dotNetColour.R;
        winRGB |= (int)dotNetColour.G << 8;
        winRGB |= (int)dotNetColour.B << 16;

        return winRGB;
    }

    static public Color ConvertWindowsRGBToColour(int windowsRGBColour)
    {
        int r = 0, g = 0, b = 0;

        // windows rgb values have byte order 0x00BBGGRR
        r = (windowsRGBColour & 0x000000FF);
        g = (windowsRGBColour & 0x0000FF00) >> 8;
        b = (windowsRGBColour & 0x00FF0000) >> 16;

        Color dotNetColour = Color.FromArgb(r, g, b);

        return dotNetColour;
    }

谢谢回复 John,ColorTranslator.ToWin32()/FromWinW32() 是做什么的?另外,OLE 颜色是什么? - JD.
2
基本上是的 - 正如Alexandre展示的那样,反汇编代码非常相似。OLE颜色的想法是它可以包括一个标志,指示颜色是系统颜色,例如“按钮面”。由于这些在不同的操作系统/主题上可能会有不同的外观,如果您想使应用程序与当前的Windows主题匹配,则它们将非常有用。如果它们不包括标志,那么它们将像Win32颜色一样运行。 - John Sibly
1
谢谢John的解释。我从来没有使用过位运算和移位操作,所以看到你的例子让我学会了如何使用它们。还要感谢下面的Alex,我将在未来尝试更多地使用Reflector。 - JD.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接