【问题标题】:how to draw a taskbar button like icon using theme api如何使用主题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,但什么也没发生,只是空白。 请指导我............

【问题讨论】:

    标签: c++ winapi themes


    【解决方案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 时设置它?
    猜你喜欢
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 2016-09-26
    • 2013-08-31
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多