Windows 10 个关闭、最小化和最大化按钮
Windows 10 Close, Minimize and Maximize buttons
绘制主题按钮我使用此代码:
var
h: HTHEME;
begin
if UseThemes then begin
SetWindowTheme(Handle, 'explorer', nil);
h := OpenThemeData(Handle, 'WINDOW');
if h <> 0 then
try
DrawThemeBackground(h, Canvas.Handle, WP_CLOSEBUTTON, GetAeroState, ClientRect, nil);
finally
CloseThemeData(h);
end;
end
else
DrawFrameControl(Canvas.Handle, ClientRect, DFC_CAPTION, DFCS_CAPTIONCLOSE or GetClassicState)
end;
这段代码工作正常,但绘制的按钮看起来像 Windows 7 主题,即使在 Windows 8 或 10 上也是如此。这可以使用 Windows 10 或8 个主题?
解决此问题的方法之一:手动解析活动*.msstyles文件。通常这是 aero.msstyles。存储在 STREAM 部分的不同 window 控件的位图。 For Windows 7 ResId = 971, Windows 8: Id = 1060, Windows 10: Id = 1194。但这是手工工作,这个位图是不同的。
更新:
我发现,即使是 Windows 的一个版本(针对 8 个版本进行了测试),我们也可以为该位图(png 图像)设置不同的资源 ID 值,现在我可以提供代码来获取任何 Windows 上的资源 ID(针对 7、8、10 测试):
function EnumStreamProc(hModule: HMODULE; AType, AName: PChar; Params: LPARAM): BOOL; stdcall;
var
Id: NativeInt;
begin
PNativeInt(Params)^ := Integer(AName);
Result := False;
end;
function GetStyleResourceId(AModule: HMODULE): Integer;
begin
Result := 0;
EnumResourceNames(AMODULE, 'STREAM', @EnumStreamProc, LPARAM(@Result));
end;
var
hLib: HMODULE;
ResId: Integer;
RS: TResourceStream;
Png: TPngImage;
begin
hLib := LoadLibraryEx(PChar(GetWindowsPath + 'Resources\Themes\Aero\aero.msstyles'),
0, LOAD_LIBRARY_AS_DATAFILE);
ResId := GetStyleResourceId(hLib);
RS := TResourceStream.CreateFromID(hLib, ResId, 'STREAM');
Png := TPngImage.Create;
Png.LoadFromStream(RS);
...
end;
更新二:
使用官方发现没有破解方法api:
var
h: HTHEME;
Rect: TRect;
PBuf, PPBuf: Pointer;
BufSize: Cardinal;
Buf: array[0..1024*1024] of Byte;
h := OpenThemeData(Handle, 'DWMWINDOW');
if h <> 0 then
try
GetThemeRect(h, WP_MINCAPTION, MNCS_ACTIVE, TMT_ATLASRECT, Rect);
PBuf := @Buf[0];
PPBuf := @PBuf;
GetThemeStream(h, WP_MINCAPTION, MNCS_ACTIVE, TMT_ATLASRECT, PBuf, BufSize, hInstance);
finally
CloseThemeData(h);
end;
我可以获取最小化按钮的Rect,但不明白如何使用GetThemeStream?应该用PBuf还是PPBuf?
从主题获取位图的可行解决方案:
var
h: HTHEME;
Rect: TRect;
BufSize: Cardinal;
h := OpenThemeData(Handle, 'DWMWINDOW');
if h <> 0 then
try
GetThemeRect(h, WP_MINCAPTION, MNCS_ACTIVE, TMT_ATLASRECT, Rect);
...
GetThemeStream(...);
finally
CloseThemeData(h);
end;
以及此处描述的如何使用 GetThemeStream:,非常感谢 Vista Style Builder 程序的作者 Andreas Verhoeven
绘制主题按钮我使用此代码:
var
h: HTHEME;
begin
if UseThemes then begin
SetWindowTheme(Handle, 'explorer', nil);
h := OpenThemeData(Handle, 'WINDOW');
if h <> 0 then
try
DrawThemeBackground(h, Canvas.Handle, WP_CLOSEBUTTON, GetAeroState, ClientRect, nil);
finally
CloseThemeData(h);
end;
end
else
DrawFrameControl(Canvas.Handle, ClientRect, DFC_CAPTION, DFCS_CAPTIONCLOSE or GetClassicState)
end;
这段代码工作正常,但绘制的按钮看起来像 Windows 7 主题,即使在 Windows 8 或 10 上也是如此。这可以使用 Windows 10 或8 个主题?
解决此问题的方法之一:手动解析活动*.msstyles文件。通常这是 aero.msstyles。存储在 STREAM 部分的不同 window 控件的位图。 For Windows 7 ResId = 971, Windows 8: Id = 1060, Windows 10: Id = 1194。但这是手工工作,这个位图是不同的。
更新:
我发现,即使是 Windows 的一个版本(针对 8 个版本进行了测试),我们也可以为该位图(png 图像)设置不同的资源 ID 值,现在我可以提供代码来获取任何 Windows 上的资源 ID(针对 7、8、10 测试):
function EnumStreamProc(hModule: HMODULE; AType, AName: PChar; Params: LPARAM): BOOL; stdcall;
var
Id: NativeInt;
begin
PNativeInt(Params)^ := Integer(AName);
Result := False;
end;
function GetStyleResourceId(AModule: HMODULE): Integer;
begin
Result := 0;
EnumResourceNames(AMODULE, 'STREAM', @EnumStreamProc, LPARAM(@Result));
end;
var
hLib: HMODULE;
ResId: Integer;
RS: TResourceStream;
Png: TPngImage;
begin
hLib := LoadLibraryEx(PChar(GetWindowsPath + 'Resources\Themes\Aero\aero.msstyles'),
0, LOAD_LIBRARY_AS_DATAFILE);
ResId := GetStyleResourceId(hLib);
RS := TResourceStream.CreateFromID(hLib, ResId, 'STREAM');
Png := TPngImage.Create;
Png.LoadFromStream(RS);
...
end;
更新二:
使用官方发现没有破解方法api:
var
h: HTHEME;
Rect: TRect;
PBuf, PPBuf: Pointer;
BufSize: Cardinal;
Buf: array[0..1024*1024] of Byte;
h := OpenThemeData(Handle, 'DWMWINDOW');
if h <> 0 then
try
GetThemeRect(h, WP_MINCAPTION, MNCS_ACTIVE, TMT_ATLASRECT, Rect);
PBuf := @Buf[0];
PPBuf := @PBuf;
GetThemeStream(h, WP_MINCAPTION, MNCS_ACTIVE, TMT_ATLASRECT, PBuf, BufSize, hInstance);
finally
CloseThemeData(h);
end;
我可以获取最小化按钮的Rect,但不明白如何使用GetThemeStream?应该用PBuf还是PPBuf?
从主题获取位图的可行解决方案:
var
h: HTHEME;
Rect: TRect;
BufSize: Cardinal;
h := OpenThemeData(Handle, 'DWMWINDOW');
if h <> 0 then
try
GetThemeRect(h, WP_MINCAPTION, MNCS_ACTIVE, TMT_ATLASRECT, Rect);
...
GetThemeStream(...);
finally
CloseThemeData(h);
end;
以及此处描述的如何使用 GetThemeStream: