Difference between revisions of "Win32MenuStyler"

From Lazarus wiki
(About)
(About)
 
(25 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
{{Platform only|Windows}}
 
=About=
 
=About=
  
This is helper unit win32menustyler, which helps to theme TMainMenu for Lazarus Windows apps.
+
This is unit win32menustyler, which helps to theme TMainMenu/TPopupMenu for Lazarus Windows apps.
 
Sometimes app has dark theme, so it's needed to make TMainMenu also dark.
 
Sometimes app has dark theme, so it's needed to make TMainMenu also dark.
  
About other OS'es: GitHub repo has cross-platform "lazmenustyler" unit, but it don't give any effect on gtk2 demo app. And it should not work on macOS since it has very special theming and menu is located on the screen top.
+
[[File:win32menustyler_.png]]
 
 
[[File:win32menustyler.png]]
 
  
 
Author: Alexey Torgashin
 
Author: Alexey Torgashin
  
 
License: MPL 2.0 or LGPL
 
License: MPL 2.0 or LGPL
 +
 +
=Detailed info=
 +
What it paints for menu items:
 +
 +
* background, caption, also for disabled state
 +
* checked state, also for radio-items
 +
* separator line
 +
* shortcut text right-aligned
 +
* sub-menu arrow
 +
* icons from ImageList
 +
* icons from menuitem.Bitmap
 +
* underlines for accelerators, and only when OS requires it (not painted until menu is activated)
 +
 +
What is not supported:
 +
 +
* menuitem.SubMenuImages
 +
* menuitem.RightJustify
 +
* white frame is painted for PopupMenus (cannot find a way to fill it, even if I call MenuStyler.ApplyBackColor in OnPopup)
 +
* horizontal white line is painted under menu bar (non-client area, must [https://stackoverflow.com/questions/57177310/how-to-paint-over-white-line-between-menu-bar-and-client-area-of-window handle WM_NCPAINT somehow])
 +
 +
About other OS: GitHub repo has cross-platform "lazmenustyler" unit, but it don't give any effect on gtk2 demo app. And it should not work on macOS, macOS has very special theming and menu is located on the screen top.
  
 
=Usage=
 
=Usage=
  
* add "uses win32menustyler"
+
* add win32menustyler to "uses"
* in form's OnCreate, call this to theme form's MainMenu:
+
* in form's OnShow, call:
 
+
** MenuStyler.ApplyToForm(Self, False) to theme MainMenu
<syntaxhighlight lang="pascal">
+
** MenuStyler.ApplyToMenu() for all needed PopupMenus
procedure TForm1.FormCreate(Sender: TObject);
+
* when needed to apply different colors later:
begin
+
** change them in global theme var
  MenuStyler.ApplyToForm(Self);
+
** call MenuStyler.ApplyToForm(Self, True): second param should be True here, this forces form's resize to repaint the menu bar
end;
+
** not needed to call again MenuStyler.ApplyToMenu() for PopupMenus
</syntaxhighlight>
+
* to cancel theming, call MenuStyler.ResetForm() and MenuStyler.ResetMenu()
  
 
Unit gives global var to change all theming details:
 
Unit gives global var to change all theming details:
Line 31: Line 51:
 
     ColorBk: TColor;
 
     ColorBk: TColor;
 
     ColorBkSelected: TColor;
 
     ColorBkSelected: TColor;
 +
    ColorBkSelectedDisabled: TColor; //used only if <>clNone
 +
    ColorSelBorder: TColor; //used only if <>clNone
 
     ColorFont: TColor;
 
     ColorFont: TColor;
 +
    ColorFontSelected: TColor; //used only if <>clNone
 
     ColorFontDisabled: TColor;
 
     ColorFontDisabled: TColor;
     CharCheckmark: Widechar;
+
    ColorFontShortcut: TColor;
     CharRadiomark: Widechar;
+
     CharCheckmark: WideChar;
 +
     CharRadiomark: WideChar;
 +
    CharSubmenu: WideChar;
 
     FontName: string;
 
     FontName: string;
 
     FontSize: integer;
 
     FontSize: integer;
     IndentX: integer;
+
     //indents in percents of average char width
     IndentX2: integer;
+
    IndentMinPercents: integer; //indent from edges to separator line
     IndentY: integer;
+
    IndentBigPercents: integer; //indent from left edge to caption
 +
    IndentIconPercents: integer; //indents around the icon
 +
     IndentRightPercents: integer; //indent from right edge to end of shortcut text
 +
     IndentSubmenuArrowPercents: integer; //indent from right edge to submenu '>' char
 
   end;
 
   end;
 +
 
var
 
var
 
   MenuStylerTheme: TWin32MenuStylerTheme;
 
   MenuStylerTheme: TWin32MenuStylerTheme;

Latest revision as of 16:01, 25 September 2020

Windows logo - 2012.svg

This article applies to Windows only.

See also: Multiplatform Programming Guide

About

This is unit win32menustyler, which helps to theme TMainMenu/TPopupMenu for Lazarus Windows apps. Sometimes app has dark theme, so it's needed to make TMainMenu also dark.

win32menustyler .png

Author: Alexey Torgashin

License: MPL 2.0 or LGPL

Detailed info

What it paints for menu items:

  • background, caption, also for disabled state
  • checked state, also for radio-items
  • separator line
  • shortcut text right-aligned
  • sub-menu arrow
  • icons from ImageList
  • icons from menuitem.Bitmap
  • underlines for accelerators, and only when OS requires it (not painted until menu is activated)

What is not supported:

  • menuitem.SubMenuImages
  • menuitem.RightJustify
  • white frame is painted for PopupMenus (cannot find a way to fill it, even if I call MenuStyler.ApplyBackColor in OnPopup)
  • horizontal white line is painted under menu bar (non-client area, must handle WM_NCPAINT somehow)

About other OS: GitHub repo has cross-platform "lazmenustyler" unit, but it don't give any effect on gtk2 demo app. And it should not work on macOS, macOS has very special theming and menu is located on the screen top.

Usage

  • add win32menustyler to "uses"
  • in form's OnShow, call:
    • MenuStyler.ApplyToForm(Self, False) to theme MainMenu
    • MenuStyler.ApplyToMenu() for all needed PopupMenus
  • when needed to apply different colors later:
    • change them in global theme var
    • call MenuStyler.ApplyToForm(Self, True): second param should be True here, this forces form's resize to repaint the menu bar
    • not needed to call again MenuStyler.ApplyToMenu() for PopupMenus
  • to cancel theming, call MenuStyler.ResetForm() and MenuStyler.ResetMenu()

Unit gives global var to change all theming details:

type
  TWin32MenuStylerTheme = record
    ColorBk: TColor;
    ColorBkSelected: TColor;
    ColorBkSelectedDisabled: TColor; //used only if <>clNone
    ColorSelBorder: TColor; //used only if <>clNone
    ColorFont: TColor;
    ColorFontSelected: TColor; //used only if <>clNone
    ColorFontDisabled: TColor;
    ColorFontShortcut: TColor;
    CharCheckmark: WideChar;
    CharRadiomark: WideChar;
    CharSubmenu: WideChar;
    FontName: string;
    FontSize: integer;
    //indents in percents of average char width
    IndentMinPercents: integer; //indent from edges to separator line
    IndentBigPercents: integer; //indent from left edge to caption
    IndentIconPercents: integer; //indents around the icon
    IndentRightPercents: integer; //indent from right edge to end of shortcut text
    IndentSubmenuArrowPercents: integer; //indent from right edge to submenu '>' char
  end;

var
  MenuStylerTheme: TWin32MenuStylerTheme;

Download

GitHub: https://github.com/Alexey-T/Win32MenuStyler