如何使用主题api绘制像图标一样的任务栏按钮

时间:2014-04-01 14:01:48

标签: c++ winapi themes

目前我正在使用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 个答案:

答案 0 :(得分:2)

1)您的deskband必须实现IOleCommandTarget。当shell使用DBID_SETWINDOWTHEME调用IOleCommandTarget.Exec时,必须将主题名称存储在变量WindowThemeSubClass中。

2)打开主题(来自我的Shell Ace lib的代码):

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不支持OpenTheme,其参数类似于' SubClass :: Class'!

3)仅在鼠标悬停在按钮上或用户按下按钮时才绘制按钮:

DrawThemeBackground(FToolBarTheme, Canvas.Handle, TP_BUTTON, State, Rec.Rect, nil);

当用户将鼠标悬停在按钮上时状态为TS_HOT,或者当用户按下按钮时状态为TS_PRESSED。

结果:

鼠标悬停在MS Tablet PC输入面板上: enter image description here

鼠标悬停在我的扩展程序上: enter image description here