В Проводнике Windows есть панели групп, например "System Tasks", "Other Places", "Details", висят они обычно слева.
Пытаюсь сам нарисовать такую панель, теперь уже средствами ThemeAPI (MS Visual Styles). В частности прорисовка любой части панели через DrawThemeBackground.
В чем проблема: когда Windows XP использует стандартную голубую тему оформления Luna, все выглядит хорошо, как в Проводнике.
Когда меняю стиль на любой другой (назависимо от того, пропатчена винда для работы с не Microsoft'овскими стилями, или нет), изображения на панели групп не соответствуют используемым в Проводнике.
При копании в системных ресурсах (програмой Restorator) выяснилось, что Theme API берет их из файла темы *.msstyles (например "Longhorn Aero.msstyles"), как вроде и предполагается. Но сам Проводник вытаскивает эти изображения
(а именно фон панели групп, заголовок и кнопки сворачивания/разворачивания, в комплектации для обычных (Normal) и специальных (Special) вариантов панели) из файла shellstyle.dll, относящегося к текущей теме. Причем эти изображения в
shellstyle.dll и
*.msstyles отличаются.
С элементами оформления кнопки никаких проблем нет, соответствующие изображения присутсвуют в *.msstyles, а в shellstyle.dll альтернатива отсутствует.
В MSDN нарыл функцию SHGetShellStyleHInstance(), которая возвращет хэндл этой
shellstyle.dll, можно обращаться к картинкам как к ресурсам в DLL, но по идее это должно выполняться через ThemeAPI стандартно.
В MSDN есть пара статей, но про эти подводные камни — ни слова, как и в статье
Поддержка Windows Visual Styles (Themes) API в Ваших органах управленияАвтор(ы): Акжан Абдулин
Дата: 04.12.2001
(с нее и начинал разбираться). А информации по ThemeApi в сети, судя по тому что наскреб при поиске, — кот наплакал. Немногие примеры относятся к прорисовке стандартной кнопки, а про панели в Explorer Bar — ни слуху, ни духу.
Вот код в C++ Builder 6. Рисует заголовок Group Panel на форме в левом верхнем углу. Используется статическая линковка с
uxtheme.lib (при динамическом подключении к
uxtheme.dll проблема остается).
typedef HINSTANCE (__stdcall *tdefSHGetShellStyleHInstance) ();
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HTHEME hTheme;
WideString themepartname;
bool FSpecialHeader;
bool FIsThemeActived;
bool FIsAppThemed;
int FHeightMin = 30;
// if(hTheme) CloseThemeData(hTheme);
hTheme = NULL;
themepartname = "ExplorerBar";
FIsThemeActived = IsThemeActive();
FIsAppThemed = IsAppThemed();
// HANDLE hwnd = Panel2->Handle;
HANDLE hwnd = this->Handle;
HDC hDC = GetDC(hwnd);
if(FIsAppThemed)
{
hTheme = OpenThemeData(hwnd, themepartname);
}
RECT rc, rcContent;
TCHAR szText[255];
HRESULT hr;
size_t cch;
int iState = 0;
GetWindowText(hwnd, szText,
(sizeof(szText)/sizeof(szText[0])+1));
WideString WideText = WideString(szText);
wchar_t *w_szstr = WideText.c_bstr();
hr = strlen(szText);
cch = hr;
HINSTANCE hShellStyle;//указатель на библиотеку стилей
HINSTANCE hShell32 = LoadLibrary("shell32.dll");
tdefSHGetShellStyleHInstance SHGetShellStyleHInstance = NULL;
SHGetShellStyleHInstance = (tdefSHGetShellStyleHInstance) GetProcAddress(hShell32, "SHGetShellStyleHInstance");//получение указателя на функцию
if(SHGetShellStyleHInstance != NULL) hShellStyle = SHGetShellStyleHInstance();//функция возвращает хэндл библиотеки стилей
FreeLibrary(hShell32);
if (hTheme)
{
//Прорисовка заголовка
//Вывод фона заголовка
Graphics::TBitmap *bmp;
rc.left = 0;
rc.top = 0;
rc.right = 150;
rc.bottom = 40;
int ebp = 0;
ebp = (FSpecialHeader ? EBP_SPECIALGROUPHEAD : EBP_NORMALGROUPHEAD);
// Always check your result codes.
//Вычисление и установка региона для панели
// HRGN HeadRgn;
// GetThemeBackgroundRegion(hTheme, hDC, ebp, iState, &rc, &HeadRgn);
// SetWindowRgn(hwnd, HeadRgn, true);
//Прорисовка фона родителя
hr = DrawThemeParentBackground(hwnd, hDC, &rc);
//Вычисление координат контента
hr = GetThemeBackgroundContentRect(hTheme,
hDC,
ebp,
iState,
&rc,
&rcContent);
// {
// bmp = new Graphics::TBitmap();
//
// bmp->LoadFromResourceID((unsigned int)hShellStyle, (FSpecialHeader ? 110 : 112));//вытаскивание картинки из ресурсов DLL
// Canvas->StretchDraw(rcContent, bmp);
// delete bmp;
// }
hr = DrawThemeBackground(hTheme, hDC, ebp,
iState, &rcContent, 0);
// hr = DrawThemeIcon(hTheme, hDC, ebp, iState, &rcContent, (HIMAGELIST)ImageList1->Handle, 2);
wchar_t *wstr = L"12345678901234567890123456789012345678901234567890";
hr = GetThemeFilename(hTheme, ebp, iState, UpDown1->Position, wstr, 50);
if(hr == S_OK) Caption = WideString(wstr);
else Caption = "Form1";
}
ReleaseDC(hwnd, hDC);
CloseThemeData(hTheme);
}
используемые идентификаторы из файла
tmschema.h:
...
//---------------------------------------------------------------------------------------
// "ExplorerBar" Parts & States
//---------------------------------------------------------------------------------------
BEGIN_TM_CLASS_PARTS(EXPLORERBAR)
TM_PART(1, EBP, HEADERBACKGROUND)
TM_PART(2, EBP, HEADERCLOSE)
TM_PART(3, EBP, HEADERPIN)
TM_PART(4, EBP, IEBARMENU)
TM_PART(5, EBP, NORMALGROUPBACKGROUND)
TM_PART(6, EBP, NORMALGROUPCOLLAPSE)
TM_PART(7, EBP, NORMALGROUPEXPAND)
TM_PART(8, EBP, NORMALGROUPHEAD)
TM_PART(9, EBP, SPECIALGROUPBACKGROUND)
TM_PART(10, EBP, SPECIALGROUPCOLLAPSE)
TM_PART(11, EBP, SPECIALGROUPEXPAND)
TM_PART(12, EBP, SPECIALGROUPHEAD)
END_TM_CLASS_PARTS()
...
Please, наставьте на путь истинный, что я не так делаю?
Примеры того, что получилось в нестандартной и в стандартной темах:

Спасибо за внимание.