This is not directly related to your question, but since you are changing colors you can also fix the corner pixels which stand out (by corner pixels I don't mean pixels at the edges of bitmap rectangle, I mean the corner of human recognizable image)
Example, in image below, there is a red pixel at the corner of the page. We want to find that red pixel and blend it with background color so that it doesn't stand out.

To find if the corner pixels, check the pixels at left and top, if both left and top are the background color then you have a corner pixel. Repeat the same for top-right, bottom-left, and bottom-right. Blend the corner pixels with background.
Instead of changing to grayscale you can change the alpha transparency as suggested by zett42.
void change(HBITMAP hbmp, bool enabled)
{
if(!hbmp)
return;
HDC memdc = CreateCompatibleDC(nullptr);
BITMAP bm;
GetObject(hbmp, sizeof(bm), &bm);
int w = bm.bmWidth;
int h = bm.bmHeight;
BITMAPINFO bi = { sizeof(BITMAPINFOHEADER), w, h, 1, 32, BI_RGB };
std::vector<uint32_t> pixels(w * h);
GetDIBits(memdc, hbmp, 0, h, &pixels[0], &bi, DIB_RGB_COLORS);
//assume that the color at (0,0) is the background color
uint32_t old_color = pixels[0];
//this is the new background color
uint32_t bk = GetSysColor(COLOR_MENU);
//swap RGB with BGR
uint32_t new_color = RGB(GetBValue(bk), GetGValue(bk), GetRValue(bk));
//define lambda functions to swap between BGR and RGB
auto bgr_r = [](uint32_t color) { return GetBValue(color); };
auto bgr_g = [](uint32_t color) { return GetGValue(color); };
auto bgr_b = [](uint32_t color) { return GetRValue(color); };
BYTE new_red = bgr_r(new_color);
BYTE new_grn = bgr_g(new_color);
BYTE new_blu = bgr_b(new_color);
//change background and modify disabled bitmap
for(auto &p : pixels)
{
if(p == old_color)
{
p = new_color;
}
else if(!enabled)
{
//blend color with background, similar to 50% alpha
BYTE red = (bgr_r(p) + new_red) / 2;
BYTE grn = (bgr_g(p) + new_grn) / 2;
BYTE blu = (bgr_b(p) + new_blu) / 2;
p = RGB(blu, grn, red); //<= BGR/RGB swap
}
}
//fix corner edges
for(int row = h - 2; row >= 1; row--)
{
for(int col = 1; col < w - 1; col++)
{
int i = row * w + col;
if(pixels[i] != new_color)
{
//check the color of neighboring pixels:
//if that pixel has background color,
//then that pixel is the background
bool l = pixels[i - 1] == new_color; //left pixel is background
bool r = pixels[i + 1] == new_color; //right ...
bool t = pixels[i - w] == new_color; //top ...
bool b = pixels[i + w] == new_color; //bottom ...
//we are on a corner pixel if:
//both left-pixel and top-pixel are background or
//both left-pixel and bottom-pixel are background or
//both right-pixel and bottom-pixel are background or
//both right-pixel and bottom-pixel are background
if(l && t || l && b || r && t || r && b)
{
//blend corner pixel with background
BYTE red = (bgr_r(pixels[i]) + new_red) / 2;
BYTE grn = (bgr_g(pixels[i]) + new_grn) / 2;
BYTE blu = (bgr_b(pixels[i]) + new_blu) / 2;
pixels[i] = RGB(blu, grn, red);//<= BGR/RGB swap
}
}
}
}
SetDIBits(memdc, hbmp, 0, h, &pixels[0], &bi, DIB_RGB_COLORS);
DeleteDC(memdc);
}
Usage:
CBitmap bmp1, bmp2;
bmp1.LoadBitmap(IDB_BITMAP1);
bmp2.LoadBitmap(IDB_BITMAP2);
change(bmp1, enabled);
change(bmp2, disabled);