IDE.MainForm.UAHHelper.pas 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. unit IDE.MainForm.UAHHelper;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Compiler form - UAH helper which has the MRU helper as ancestor
  8. This adds support for dark menu bars, meaning just the row which displays
  9. 'File', 'Edit', etc. Support for dark menus, meaning the actual popups,
  10. is enabled using SetPreferredAppMode and FlushMenuThemes in IDE.MainForm
  11. Not used by MainForm: it uses IDE.MainForm.FinalHelper instead
  12. }
  13. interface
  14. uses
  15. Messages,
  16. NewUxTheme,
  17. IDE.MainForm, IDE.MainForm.MRUHelper;
  18. type
  19. TMainFormUAHHelper = class helper(TMainFormMRUHelper) for TMainForm
  20. procedure UAHDrawMenu(const UAHMenu: PUAHMenu);
  21. procedure UAHDrawMenuItem(const UAHDrawMenuItem: PUAHDrawMenuItem);
  22. procedure UAHDrawMenuBottomLine;
  23. end;
  24. implementation
  25. uses
  26. Windows,
  27. Classes, Graphics,
  28. ModernColors;
  29. procedure TMainFormUAHHelper.UAHDrawMenu(const UAHMenu: PUAHMenu);
  30. begin
  31. var MenuBarInfo: TMenuBarInfo;
  32. MenuBarInfo.cbSize := SizeOf(MenuBarInfo);
  33. GetMenuBarInfo(Handle, Integer(OBJID_MENU), 0, MenuBarInfo);
  34. var WindowRect: TRect;
  35. GetWindowRect(Handle, WindowRect);
  36. var Rect := MenuBarInfo.rcBar;
  37. OffsetRect(Rect, -WindowRect.Left, -WindowRect.Top);
  38. FillRect(UAHMenu.hdc, Rect, FMenuDarkBackgroundBrush.Handle);
  39. end;
  40. procedure TMainFormUAHHelper.UAHDrawMenuItem(const UAHDrawMenuItem: PUAHDrawMenuItem);
  41. const
  42. ODS_NOACCEL = $100;
  43. DTT_TEXTCOLOR = 1;
  44. MENU_BARITEM = 8;
  45. MBI_NORMAL = 1;
  46. var
  47. Buffer: array of Char;
  48. begin
  49. var MenuItemInfo: TMenuItemInfo;
  50. MenuItemInfo.cbSize := SizeOf(MenuItemInfo);
  51. MenuItemInfo.fMask := MIIM_STRING;
  52. MenuItemInfo.dwTypeData := nil;
  53. GetMenuItemInfo(UAHDrawMenuItem.um.hmenu, UAHDrawMenuItem.umi.iPosition, True, MenuItemInfo);
  54. Inc(MenuItemInfo.cch);
  55. SetLength(Buffer, MenuItemInfo.cch);
  56. MenuItemInfo.dwTypeData := @Buffer[0];
  57. GetMenuItemInfo(UAHDrawMenuItem.um.hmenu, UAHDrawMenuItem.umi.iPosition, True, MenuItemInfo);
  58. var dwFlags: DWORD := DT_CENTER or DT_SINGLELINE or DT_VCENTER;
  59. if (UAHDrawMenuItem.dis.itemState and ODS_NOACCEL) <> 0 then
  60. dwFlags := dwFlags or DT_HIDEPREFIX;
  61. var Inactive := (UAHDrawMenuItem.dis.itemState and ODS_INACTIVE) <> 0;
  62. var TextColor: TThemeColor;
  63. if Inactive then
  64. TextColor := tcMarginFore
  65. else
  66. TextColor := tcFore;
  67. var opts: TDTTOpts;
  68. opts.dwSize := SizeOf(opts);
  69. opts.dwFlags := DTT_TEXTCOLOR;
  70. opts.crText := TColorRef(ColorToRGB(FTheme.Colors[TextColor]));
  71. var Brush: HBrush;
  72. { ODS_HOTLIGHT can be set when the menu is inactive so we check Inactive as well. }
  73. if not Inactive and ((UAHDrawMenuItem.dis.itemState and (ODS_HOTLIGHT or ODS_SELECTED)) <> 0) then
  74. Brush := FMenuDarkHotOrSelectedBrush.Handle
  75. else
  76. Brush := FMenuDarkBackgroundBrush.Handle;
  77. FillRect(UAHDrawMenuItem.um.hdc, UAHDrawMenuItem.dis.rcItem, Brush);
  78. DrawThemeTextEx(FMenuThemeData, UAHDrawMenuItem.um.hdc, MENU_BARITEM, MBI_NORMAL, MenuItemInfo.dwTypeData, Integer(MenuItemInfo.cch), dwFlags, @UAHDrawMenuItem.dis.rcItem, opts);
  79. end;
  80. { Should be removed if the main menu ever gets removed }
  81. procedure TMainFormUAHHelper.UAHDrawMenuBottomLine;
  82. begin
  83. if not (csDestroying in ComponentState) and (FTheme <> nil) and FTheme.Dark then begin
  84. var ClientRect: TRect;
  85. Windows.GetClientRect(Handle, ClientRect);
  86. MapWindowPoints(Handle, 0, ClientRect, 2);
  87. var WindowRect: TRect;
  88. GetWindowRect(Handle, WindowRect);
  89. var Rect := ClientRect;
  90. OffsetRect(Rect, -WindowRect.Left, -WindowRect.Top);
  91. Rect.Bottom := Rect.Top;
  92. Dec(Rect.Top);
  93. var DC := GetWindowDC(Handle);
  94. FillRect(DC, Rect, FMenuDarkBackgroundBrush.Handle);
  95. ReleaseDC(Handle, DC);
  96. end;
  97. end;
  98. end.