Winapi Windows 10关闭、最小化和最大化按钮

Winapi Windows 10关闭、最小化和最大化按钮,winapi,windows-themes,Winapi,Windows Themes,要绘制主题按钮,我使用以下代码: 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, GetA

要绘制主题按钮,我使用以下代码:

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;
var
h:血红素;
开始
如果使用主题,则开始
SetWindowTheme(句柄“explorer”,无);
h:=OpenMetadata(句柄“窗口”);
如果h0那么
尝试
DrawThemeBackground(h,Canvas.Handle,WP_CLOSEBUTTON,GetAeroState,ClientRect,无);
最后
近心资料(h);
结束;
结束
其他的
DrawFrameControl(Canvas.Handle、ClientRect、DFC_标题、DFCS_标题Close或GetClassicState)
结束;
此代码运行良好,但绘制的按钮类似于Windows7主题,即使在Windows8或10上也是如此。这是否可以使用Windows 10或8主题绘制关闭按钮


解决此问题的方法之一:手动解析活动的*.msstyles文件。通常这是aero.msstyles。流节中存储的不同窗口控件的位图。对于Windows 7,ResId=971,Windows 8:Id=1060,Windows 10:Id=1194。但这是手工操作,而位图则不同

更新:

我发现,即使对于一个版本的Windows(测试了8个版本),我们也可以为这个位图(png图像)提供不同的资源id值,现在我可以提供代码来获取任何窗口上的资源id(测试了7,8,10个版本):

更新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;
var
h:血红素;
Rect:TRect;
PBuf,PPBuf:指针;
BufSize:红衣主教;
Buf:字节的数组[0..1024*1024];
h:=OpenThemeData(句柄“DWMWINDOW”);
如果h0那么
尝试
建立(h,WP_MINCAPTION,跨国公司活跃,TMT_ATLASRECT,Rect);
PBuf:=@Buf[0];
PPBuf:=@PBuf;
GetThemeStream(h、WP_MINCAPTION、跨国公司活跃、TMT_ATLASRECT、PBuf、BufSize、hInstance);
最后
近心资料(h);
结束;

我可以得到最小化按钮的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;
var
h:血红素;
Rect:TRect;
BufSize:红衣主教;
h:=OpenThemeData(句柄“DWMWINDOW”);
如果h0那么
尝试
建立(h,WP_MINCAPTION,跨国公司活跃,TMT_ATLASRECT,Rect);
...
GetThemeStream(…);
最后
近心资料(h);
结束;

以及如何使用此处描述的GetThemeStream:,非常感谢Andreas Verhoeven,他是程序Vista样式生成器的作者

您使用的是什么版本的Delphi?添加了标记Delphi-xe7,这对这一点并不重要(我想),而且,我是在Window 8下开发的,但这就像是在Windows7下画的,你的问题不太清楚。按照我的理解,你正在尝试绘制一个与Windows版本相匹配的主题。默认情况下,这应该在没有任何编码的情况下发生。听起来您使用的是一个非常旧的Delphi版本,没有运行时主题。你能提供你所期望的和你所看到的截图吗?我认为你不可能做你想做的事。我想你需要自己画。我不认为有一个api。我还认为这个问题被贴上了很糟糕的标签。不管@Jerry怎么说,你知道,这不是Delphi的问题。如果我是你,我会删除Delphi标记,然后用
winapi
重新标记。对实现细节进行黑客攻击是不可行的。这是个很坏的主意。为什么这是个坏主意?要解决这个问题,我们有三种可能性:1。使用官方api(未提供);2.创建按钮的屏幕截图(这很容易,但不支持其他主题);3.提供了阅读主题png内容的代码(目前我正在准备解析这个png,这将支持不同的主题)。我很高兴听到另一个更方便的解决方案,因为它无法可靠地工作,因为即使您已经发现其他调查显示,Wine和ReactOS的人员都有读取*.msstyles文件的源代码。这项工作可以在阅读了这个源代码之后完成:它一直工作到发布新版本的操作系统为止
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;