Как изменить цвет фона ленты UIRibbon?

Задача изменить фоновый цвет ленты соответственно документации в окне чужого процесса, к которому есть доступ. Я пробовал средствами Detours использовать перехват функции CoCreateInstance, но не понимаю, как получить доступ к экземпляру g_pFramework:

HRESULT WINAPI DetoursHooks::MyCoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv)
{
    auto callerModule{ DetourGetContainingModule(_ReturnAddress()) };
    auto result{ actualCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv) };
    
    LPOLESTR lplpsz{};

    if (IsEqualGUID(rclsid, CLSID_UIRibbonFramework))
    {
        if (!IsEqualGUID(riid, IID_IUnknown))
        {
            IUIFramework* g_pFramework{ &ppv }; // здесь я пытаюсь получить доступ к экземпляру
            CComPtr<IPropertyStore> spPropertyStore;
            if (g_pFramework && SUCCEEDED(g_pFramework->QueryInterface(&spPropertyStore)))
            {
                
                PROPVARIANT propvarBackground;

                // UI_HSBCOLOR is a type defined in UIRibbon.h that is composed of 
                // three component values: hue, saturation and brightness, respectively.
                UI_HSBCOLOR BackgroundColor = UI_HSB(0, 0, 0);

                InitPropVariantFromUInt32(BackgroundColor, &propvarBackground);

                spPropertyStore->SetValue(UI_PKEY_GlobalBackgroundColor, propvarBackground);

                spPropertyStore->Commit();
            }
        }
    }
    
    return result;
}

И верное ли направление в решении я выбрал, может эту задачу можно решить иным способом? Прошу помощи.

Немного поэкспериментировал и указатель на интерфейс получил просто:

memcpy(&g_pFramework, ppv, sizeof(ppv));

Но это не принесло ожидаемого результата - фон не меняется, можно изменить только цвет текста.


Ответы (1 шт):

Автор решения: Стас Палыч

Опытным путем нашел способ изменить цвет фона. Лента рисует фон в функции StretchBlt, используя пиксельный bitmap, создаваемый однократно при создании ленты. Здесь следует заполнить Rect нужным цветом. Мне нужен был черный цвет, поэтому я сделал просто:

BOOL WINAPI MyStretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop)
{
    rop = BLACKNESS;
    return actualStretchBlt(hdcDest, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, rop);
}

Плюс к этому фон следует нарисовать еще в области кнопок Tab ленты. Для этого достаточно одной перехваченной функции GetStockObject и создать в ней кисть своего цвета, а мне для черного цвета было достаточно этого:

HGDIOBJ WINAPI MyGetStockObject(int i)
{
    if (i == WHITE_BRUSH || i == DC_BRUSH)
    {
        i = BLACK_BRUSH;
    }

    return actualGetStockObject(i);
}
→ Ссылка