Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows 10 Close, Minimize and Maximize buttons

to paint themed button I use this code:

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;

This code works fine but painted button looks like from Windows 7 theme, even on Windows 8 or 10. This is possible to paint the Close button using Windows 10 or 8 theme?

enter image description here

like image 789
Alex Egorov Avatar asked Nov 30 '15 17:11

Alex Egorov


People also ask

Why is the close minimize maximize buttons missing?

Press Ctrl + Shift + Esc to start Task Manager. When Task Manager opens, locate Desktop Windows Manager, right click it and choose End Task. The process will now restart and the buttons should appear again.

How do you minimize and maximize Windows 10?

Windows key + Down Arrow = Minimize the desktop window. Windows key + Right Arrow = Maximize window on right side of the screen.


1 Answers

One of ways to resolve this question: manual parsing active *.msstyles file. Usual this is aero.msstyles. Bitmap for different window controls stored in STREAM section. For Windows 7 ResId = 971, Windows 8: Id = 1060, Windows 10: Id = 1194. But this is manual work and this bitmaps is different.

Update:

I found, that even for one version of the Windows (tested for 8) we can have different values of the resource id for this Bitmap (png image) and now I can provide the code to obtain resource id on any Windows (tested for 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;

Update 2:

Found not hacked method using official 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;

I can get Rect for minimized button, but don't understand how to use GetThemeStream? There should be used PBuf or PPBuf?

like image 109
Alex Egorov Avatar answered Dec 28 '22 08:12

Alex Egorov