如何使用主题api绘制任务栏按钮,如图标
Posted
技术标签:
【中文标题】如何使用主题api绘制任务栏按钮,如图标【英文标题】:how to draw a taskbar button like icon using theme api 【发布时间】:2014-04-01 14:01:48 【问题描述】:目前我正在使用 c++ 开发桌带。现在我可以在任务栏窗口中画东西,我想画一个任务栏按钮,比如图标。我相信它不会太复杂,因为默认的触摸键盘和 TouchMousePointer 已经做到了。
我首先创建一个空白窗口,并使用主题 api 来绘制背景。但我真的不知道如何制作任务栏按钮。目前只有静态图标或半透明按钮(只有上面的文字是透明的)有效。
在这篇文章中 How do you draw a Taskbar button using visual styles? 他们通过使用 .net 提到了一些东西,但我真的不想这样做。只是想保持一切简单。(没有 mfc 或 .net)
这篇文章中还有一些信息 How to draw Windows 7 taskbar like Shaded Buttons 但不是很有用。
我还检查了 TipBand.dll(默认触摸键盘)的导入功能
UxTheme.dll
18000D088 Import Address Table
18000D668 Import Name Table
0 time date stamp
0 Index of first forwarder reference
9 CloseThemeData
11 DrawThemeParentBackground
D DrawThemeBackground
50 SetWindowTheme
4D OpenThemeData
COMCTL32.dll
18000D0B8 Import Address Table
18000D698 Import Name Table
0 time date stamp
0 Index of first forwarder reference
7C InitCommonControlsEx
GDI32.dll
18000D358 Import Address Table
18000D938 Import Name Table
0 time date stamp
0 Index of first forwarder reference
2D4 SelectObject
4C CreatePen
56 CreateSolidBrush
10E DeleteObject
261 LineTo
26F MoveToEx
他还在 user32.dll 中使用了 DrawIconEx,我试过了,但只是一个静态图标。
我也尝试了主题 api drawicon,但什么也没发生,只是空白。 请指导我............
【问题讨论】:
【参考方案1】:1) 您的桌带必须实现 IOleCommandTarget。当 shell 使用 DBID_SETWINDOWTHEME 调用 IOleCommandTarget.Exec 时,您必须将主题名称存储在变量 WindowThemeSubClass 中。
2) 打开主题(来自我的 Shell Ace 库的代码):
FToolBarTheme := IntOpenThemeData(Handle, 'TOOLBAR', WindowThemeSubClass)
...
class function TdecShellExplorerForm.IntOpenThemeData(AWnd: HWND; const AClass, ASubClass: UnicodeString): HTHEME;
var
Temp: TForm;
begin
if ASubClass = '' then
Result := OpenThemeData(AWnd, PWideChar(AClass))
else
if IsWindowsVistaOrLater then
begin
Result := OpenThemeData(AWnd, PWideChar(ASubClass + '::' + AClass));
if Result = 0 then
Result := OpenThemeData(AWnd, PWideChar(AClass));
end
else
begin
Temp := TForm.Create(Application);
try
SetWindowTheme(Temp.Handle, PWideChar(ASubClass), nil);
Result := OpenThemeData(Temp.Handle, PWideChar(AClass));
if Result = 0 then
Result := OpenThemeData(AWnd, PWideChar(AClass));
finally
Temp.Free;
end;
end;
end;
XP 不支持带有 'SubClass::Class' 等参数的 OpenTheme!
3) 仅当鼠标悬停在您的按钮上或用户按下您的按钮时才绘制按钮:
DrawThemeBackground(FToolBarTheme, Canvas.Handle, TP_BUTTON, State, Rec.Rect, nil);
当用户将鼠标悬停在您的按钮上时状态为 TS_HOT,或者当用户按下您的按钮时状态为 TS_PRESSED。
结果:
鼠标悬停在 MS Tablet PC 输入面板上:
鼠标悬停在我的扩展上:
【讨论】:
对了,图片是怎么设置的?您在创建按钮或使用 gdi 时设置它?以上是关于如何使用主题api绘制任务栏按钮,如图标的主要内容,如果未能解决你的问题,请参考以下文章