Как изменить цвет фона ленты 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);
}