3

I'm making a program and I need to paint a rectangle of the same color as the title bar.

If I try to get the color like this:

ARGB rgbActiveColor = GetSysColor(COLOR_ACTIVECAPTION);
ARGB rgbInactiveColor = GetSysColor(COLOR_INACTIVECAPTION);
rgbActiveColor |= 0xFF000000;    // Because of alpha
rgbInactiveColor |= 0xFF000000;

I get a totally different color in Windows 8. It always returns a orange or brown color instead of the actual color (let's say, blue).

Using DwmGetColorizationColor works, but the color is darker because I need to eliminate alpha. I try to do it like this:

BYTE r = ((RED * ALPHA) + (255 * (255 - ALPHA))) / 255; // R' = (R * A) + (1 - A)
BYTE g = ((GREEN * ALPHA) + (255 * (255 - ALPHA))) / 255; // G' = (G * A) + (1 - A)
BYTE b = ((BLUE * ALPHA) + (255 * (255 - ALPHA))) / 255; // B' = (B * A) + (1 - A)

So, my problems are:

  1. I don't know how I can correctly convert the return color from ARGB to RGB
  2. I don't know how to get the inactive title bar color

EDIT: My ARGB to RGB code seems to work unless I set color intensity in Control Panel to max (because somehow alpha is 0, and the color is green) or min.

EDIT2: This is not a duplicate because this is specifically about W8+.

LHLaurini
  • 1,737
  • 17
  • 31
  • Have you tried `COLORREF rgb = RGB((BYTE)rgbActiveColor >> 16, (BYTE)rgbActiveColor >> 8, (BYTE)rgbActiveColor);` – Cyclonecode Jun 27 '15 at 17:14
  • @Cyclone Yes. For some reason, the color gets green. WTF. – LHLaurini Jun 27 '15 at 17:21
  • Okay, so I changed the color and for some reason it worked. But when I set color intensity to max (in the customizing menu), alpha is 0x00 and it all fails. Now I'm REALLY confused. – LHLaurini Jun 27 '15 at 17:29
  • 1
    Isn't `GetSysColor()` only returning `RGB` and not `RGBA`? – Cyclonecode Jun 27 '15 at 17:34
  • @Cyclone `0xe37ebdf4` for blue with normal intensity but `0x008fd712`for max intensity. Also docs say "The color format of the value is 0xAARRGGBB." – LHLaurini Jun 27 '15 at 17:36
  • This might help http://stackoverflow.com/questions/12528228/how-to-get-the-caption-color-of-an-active-window-in-windows-8 – Cyclonecode Jun 27 '15 at 17:44
  • @Cyclone I don't know what can I do anymore. `DwmGetColorizationColor` doesn't work right, `GetThemeSysColor` returns the same as `GetSysColor`, `GetThemeColor(hTheme, WP_CAPTION, CS_ACTIVE, TMT_ACTIVECAPTION, &rgbBorderColor)` returns error... – LHLaurini Jun 27 '15 at 18:41
  • And `GetThemeColor(hTheme, WP_CAPTION, CS_ACTIVE, TMT_COLORIZATIONCOLOR, &rgbBorderColor)` returns gray. – LHLaurini Jun 27 '15 at 18:50
  • possible duplicate of [Vista/7: How to get glass color?](http://stackoverflow.com/questions/3560890/vista-7-how-to-get-glass-color) – Jonathan Potter Jun 27 '15 at 21:53
  • @JonathanPotter I'm going to change the title, because this question is actually only about W8. – LHLaurini Jun 27 '15 at 21:56

1 Answers1

0

This is a hackish solution and will probably only work with Windows 8 and 8.1 (I'm going to test later with 10).

I analysed the windows colors and this is what I could see:

  • Active window title (or caption) color is the result of blending between 0xD9D9D9 and the color in \HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor using the value in \HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColorBalance (it's in a 0-100 scale) as a "alpha".
  • Inactive windows have the color 0xEBEBEB

So...

if (fActive)
{
    DWORD ColorizationColor;
    DWORD ColorizationColorBalance;
    DWORD size = sizeof(DWORD);

    RegGetValue(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\DWM", L"ColorizationColor", RRF_RT_REG_DWORD, 0, &ColorizationColor, &size);
    RegGetValue(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\DWM", L"ColorizationColorBalance", RRF_RT_REG_DWORD, 0, &ColorizationColorBalance, &size);

    BYTE ALPHA = 255 * ColorizationColorBalance / 100; // Convert from 0-100 to 0-255
    BYTE RED = (ColorizationColor >> 16) & 0xFF;
    BYTE GREEN = (ColorizationColor >> 8) & 0xFF;
    BYTE BLUE = ColorizationColor & 0xFF;

    BYTE r = ((RED * ALPHA) + (0xD9 * (255 - ALPHA))) / 255;
    BYTE g = ((GREEN * ALPHA) + (0xD9 * (255 - ALPHA))) / 255;
    BYTE b = ((BLUE * ALPHA) + (0xD9 * (255 - ALPHA))) / 255;

    graphics.FillRectangle(&SolidBrush(Color(r, g, b)), Rect(...);
}
else
{
    graphics.FillRectangle(&SolidBrush(0xFFEBEBEB), Rect(...));
}

Because this probably won't work at Windows 7 different code should be user for different systems.

LHLaurini
  • 1,737
  • 17
  • 31