Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
300 views
in Technique[技术] by (71.8m points)

c - GetThemeStream usage

I'm very confused with GetThemeStream function

HRESULT GetThemeStream(
  _In_  HTHEME    hTheme,
  _In_  int       iPartId,
  _In_  int       iStateId,
  _In_  int       iPropId,
  _Out_ VOID      **ppvStream,
  _Out_ DWORD     *pcbStream,
  _In_  HINSTANCE hInst
);

How to use this function? Which parameter I should pass to the ppvStream?

Update:

I'm trying to use it with delphi, declaration from UxTheme:

function GetThemeStream(hTheme: HTHEME; iPartId: Integer; iStateId: Integer;
  iPropId: Integer; var ppvStream: Pointer; var pcbStream: DWORD;
  hInst: HINST): HResult; stdcall;

var
  h: HTHEME;
  Res: HResult;
  PBuf, PPBuf: Pointer;
  BufSize: Cardinal;


h := OpenThemeData(Handle, 'DWMWINDOW');
if h = 0 then Exit;
PBuf := nil;
PPBuf := @PBuf;
Res := GetThemeStream(h, WP_FRAMELEFT, CBS_HOT, TMT_DISKSTREAM, PPBuf, BufSize, hInstance);
if Res <> S_OK then Exit;

Here I'm have BufSize = 75005, Res = S_OK, but nothing in PBuf (nil), possible I'm incorrect send parameter?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Correct usage of this function, thanks to Andreas Verhoeven, author of the program Vista Style Builder:

var
  hTh: HTHEME;
  hLib: HMODULE;
  DllName: string;
  Png: TPngImage;
  MS: TMemoryStream;
  BufSize: Cardinal;
  PBuf: Pointer;

hTh := OpenThemeData(...);
// DllName is path to the theme file
hLib := LoadLibraryEx(PChar(DllName), 0, LOAD_LIBRARY_AS_DATAFILE);
// Read Theme Png stream
GetThemeStream(hTh, 0, 0, TMT_DISKSTREAM, PBuf, BufSize, hLib);
// Copy data to memory stream
MS := TMemoryStream.Create;
MS.WriteBuffer(PByteArray(PBuf)^[0], BufSize);
MS.Position := 0;
// Copy memory stream to Png
Png := TPngImage.Create;
Png.LoadFromStream(MS);

Update with additional example:

var
  ThemeRectLeft,
  ThemeRectLeftInactive,
  ThemeRectMiddle,
  ThemeRectMiddleInactive,
  ThemeRectCloseRight,
  ThemeRectCloseRightInactive,
  ThemeRectCloseSingle,
  ThemeRectCloseSingleInactive,
  ThemeRectMinIco,
  ThemeRectMaxIco,
  ThemeRectRestoreIco,
  ThemeRectHelpIco,
  ThemeRectCloseIco: TRect;

var
  THEME_MIDDLE_IMAGES         : Integer =  3;
  THEME_MIDDLE_IMAGES2        : Integer =  4; // Inactive Window
  THEME_LEFT_IMAGES           : Integer =  5;
  THEME_LEFT_IMAGES2          : Integer =  6; // Inactive Window
  THEME_CLOSE_RIGHT_IMAGES    : Integer =  7;
  THEME_CLOSE_RIGHT_IMAGES2   : Integer =  8; // Inactive Window
  THEME_CLOSE_SINGLE_IMAGES   : Integer =  9;
  THEME_CLOSE_SINGLE_IMAGES2  : Integer = 10; // Inactive Window
  THEME_CLOSE_HOT_FRAME       : Integer = 11; // Win7, Vista
  THEME_HOT_FRAME             : Integer = 16; // Win7, Vista
  THEME_CLOSE_ICONS           : Integer = 12;
  THEME_HELP_ICONS            : Integer = 16; // Win7, Vista: 17
  THEME_MAX_ICONS             : Integer = 20; // Win7, Vista: 21
  THEME_MIN_ICONS             : Integer = 24; // Win7, Vista: 25
  THEME_RESTORE_ICONS         : Integer = 28; // Win7, Vista: 29
  THEME_CLOSE_SMALL_IMAGES    : Integer = 37; // Win7, Vista: 45
  THEME_CLOSE_SMALL_IMAGES2   : Integer = 38; // Win7, Vista: 46  Inactive Window
  THEME_CLOSE_SMALL_HOT_FRAME : Integer = 47; // Win7, Vista
  THEME_CLOSE_SMALL_ICONS     : Integer = 39; // Win7, Vista: 48

function LoadThemePng(var APng: TPngImage; const APathToSave: string): Boolean;
const
  ThemeRegPath = 'SOFTWAREMicrosoftWindowsCurrentVersionThemeManager';
var
  hTh: HTHEME;
  hLib: HMODULE;
  DllName, Path: string;
  MS: TMemoryStream;
  BufSize: Cardinal;
  PBuf: Pointer;
  I: Integer;
  Rt: TRect;
  imgPng: TPngImage;
begin
  Result := False;
  hTh := OpenThemeData(0, 'DWMWINDOW');
  if hTh <> 0 then
  try
    // Get Library path
    SetLength(DllName, 1024);
    SHRegGetPath(HKEY_CURRENT_USER, PChar(ThemeRegPath), 'DllName', PChar(DllName), 0);
    // Open Library
    hLib := LoadLibraryEx(PChar(DllName), 0, LOAD_LIBRARY_AS_DATAFILE);
    if hLib > 0 then
    try
      // Read Theme Png stream
      if GetThemeStream(hTh, 0, 0, TMT_DISKSTREAM, PBuf, BufSize, hLib) = S_OK then begin
        MS := TMemoryStream.Create;
        try
          MS.WriteBuffer(PByteArray(PBuf)^[0], BufSize);
          MS.Position := 0;
          APng.LoadFromStream(MS);
          Result := True;
        finally
          MS.Free;
        end;
      end;
    finally
      FreeLibrary(hLib);
    end;
    GetThemeRect(hTh, THEME_LEFT_IMAGES, 0, TMT_ATLASRECT, ThemeRectLeft);
    GetThemeRect(hTh, THEME_LEFT_IMAGES2, 0, TMT_ATLASRECT, ThemeRectLeftInactive);
    GetThemeRect(hTh, THEME_MIDDLE_IMAGES, 0, TMT_ATLASRECT, ThemeRectMiddle);
    GetThemeRect(hTh, THEME_MIDDLE_IMAGES2, 0, TMT_ATLASRECT, ThemeRectMiddleInactive);
    GetThemeRect(hTh, THEME_CLOSE_RIGHT_IMAGES,  0, TMT_ATLASRECT, ThemeRectCloseRight);
    GetThemeRect(hTh, THEME_CLOSE_RIGHT_IMAGES2,  0, TMT_ATLASRECT, ThemeRectCloseRightInactive);
    GetThemeRect(hTh, THEME_CLOSE_SINGLE_IMAGES,  0, TMT_ATLASRECT, ThemeRectCloseSingle);
    GetThemeRect(hTh, THEME_CLOSE_SINGLE_IMAGES2,  0, TMT_ATLASRECT, ThemeRectCloseSingleInactive);

    if (Win32MajorVersion = 6) and (Win32MinorVersion in [0, 1]) then begin
      GetThemeRect(hTh, THEME_MIN_ICONS + 1,     0, TMT_ATLASRECT, ThemeRectMinIco);
      GetThemeRect(hTh, THEME_MAX_ICONS + 1,     0, TMT_ATLASRECT, ThemeRectMaxIco);
      GetThemeRect(hTh, THEME_RESTORE_ICONS + 1, 0, TMT_ATLASRECT, ThemeRectRestoreIco);
      GetThemeRect(hTh, THEME_HELP_ICONS + 1,    0, TMT_ATLASRECT, ThemeRectHelpIco);
    end
    else begin
      GetThemeRect(hTh, THEME_MIN_ICONS,     0, TMT_ATLASRECT, ThemeRectMinIco);
      GetThemeRect(hTh, THEME_MAX_ICONS,     0, TMT_ATLASRECT, ThemeRectMaxIco);
      GetThemeRect(hTh, THEME_RESTORE_ICONS, 0, TMT_ATLASRECT, ThemeRectRestoreIco);
      GetThemeRect(hTh, THEME_HELP_ICONS,    0, TMT_ATLASRECT, ThemeRectHelpIco);
    end;

    GetThemeRect(hTh, THEME_CLOSE_ICONS,   0, TMT_ATLASRECT, ThemeRectCloseIco);

    if APathToSave <> '' then begin
      Path := IncludeTrailingPathDelimiter(APathToSave);
      APng.SaveToFile(Path + 'Theme_Full.png');
      for I := 1 to 99 do begin
        imgPng := TPngImage.Create;
        try
          if GetThemeRect(hTh, I, 0, TMT_ATLASRECT, Rt) = S_OK then begin
            CopyPng(APng, imgPng, Rt);
            imgPng.SaveToFile(Path + 'Theme_Img_' + IntToStr(I) + '.png');
          end;
        finally
          imgPng.Free;
        end;
      end;
    end;
  finally
    CloseThemeData(hTh);
  end;
end;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...