绘制主题按钮,我使用以下代码:
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 8或10上,绘制按钮的外观也与Windows 7主题类似。可以使用Windows 10或8主题绘制“关闭”按钮吗?
最佳答案
解决此问题的方法之一:手动解析 Activity 的 * .msstyles 文件。通常这是aero.msstyles。存储在STREAM部分中的不同窗口控件的位图。对于Windows 7 ResId = 971,对于Windows 8:Id = 1060,对于Windows 10:Id =1194。但这是手动工作,并且此位图有所不同。
更新:
我发现,即使对于Windows的一个版本(已测试8),我们对于该位图(png图像)也可以具有不同的资源ID值,现在,我可以提供代码以在任何Windows(已测试7)上获取资源ID。 ,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;
更新2:
使用官方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?
关于winapi - Windows 10关闭,最小化和最大化按钮,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34004819/