一個方法來解決這個問題:手工解析活躍* .msstyles文件。通常這是aero.msstyles。存儲在STREAM部分中的不同窗口控件的位圖。對於Windows 7 ResId = 971,Windows 8:Id = 1060,Windows 10:Id = 1194。但這是手動工作,此位圖不同。
更新:
我發現,在Windows(8測試)即使對於一個版本中,我們可以有資源ID的不同值此位圖(PNG圖像),現在我可以提供代碼獲取任何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;
更新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;
我可以得到最小化按鈕的矩形,但不明白如何使用GetThemeStream?應該使用PBuf還是PPBuf?
是什麼版本的Delphi的作者你在用嗎? –
添加了delphi-xe7標籤,這對我來說並不重要,我也是在Window 8下開發的,但是它的繪製方式類似於Windows 7 –
問題不是很清楚。我理解它的方式,你試圖繪製一個匹配Windows版本的主題。這應該在沒有任何編碼的情況下發生。這聽起來像你使用的是一個非常老的Delphi版本,沒有運行時主題。你能提供你所期望的和你看到的東西的截圖嗎? –