如何在 Inno Setup Pascal 脚本中变亮或变暗指定的 TColor?

GTA*_*ver 1 inno-setup percentage pascalscript tcolor

我需要TPanel根据我的wpInfoBefore向导页面中显示的用户当前的系统规格自动更改状态栏的颜色(它是一个)(变亮或变暗)。

我喜欢有两个函数可以通过输入 aTColor作为值来正确执行此操作。但是,我多次尝试通过阅读这样的帖子来编写这些函数甚至使用RGB函数,但没有成功。

例如,如果我需要使给定的变暗或变亮TColor,我可能需要使用如下所示的函数:

var
   RecommendedStatusColor: TColor;

function LightenColor(Colour: TColor, Percentage: Integer): TColor;
begin 
   ...
end;

function DarkenColor(Colour: TColor, Percentage: Integer): TColor;
begin 
   ...
end;    

RecommendedStatusColor := $00D000;

if ... then
StatusBar.Color := LightenColor(RecommendedStatusColor, 75);
//Lighten given color by 75%

if ... then
StatusBar.Color := DarkenColor(RecommendedStatusColor, 50);
//Darken given color by 50%
Run Code Online (Sandbox Code Playgroud)

应修改输出(变亮或变暗)TColor.

提前致谢。

Mar*_*ryl 5

您必须将颜色转换为HSL 或 HSV,并更改亮度 (L) 或值 (V),然后转换回 RGB。

\n

以下代码使用 HSL(L = 亮度)。

\n\n
function GetRValue(RGB: Cardinal): Byte;\nbegin\n  Result := Byte(rgb);\nend;\n\nfunction GetGValue(RGB: Cardinal): Byte;\nbegin\n  Result := Byte(rgb shr 8);\nend;\n\nfunction GetBValue(RGB: Cardinal): Byte;\nbegin\n  Result := Byte(rgb shr 16);\nend;\n\nfunction Max(A, B: Integer): Integer;\nbegin\n  if A > B then\n    Result := A\n  else\n    Result := B;\nend;\n\nfunction Min(A, B: Integer): Integer;\nbegin\n  if A < B then\n    Result := A\n  else\n    Result := B;\nend;\n\nconst\n  HLSMAX = 240;\n  RGBMAX = 255;\n  HLSUndefined = (HLSMAX*2/3);\n  \nprocedure ColorRGBToHLS(RGB: Cardinal; var Hue, Luminance, Saturation: Word);\nvar\n  H, L, S: Double;\n  R, G, B: Word;\n  cMax, cMin: Double;\n  Rdelta, Gdelta, Bdelta: Word; { intermediate value: % of spread from max }\nbegin\n  R := GetRValue(RGB);\n  G := GetGValue(RGB);\n  B := GetBValue(RGB);\n\n  { calculate lightness }\n  cMax := Max(Max(R, G), B);\n  cMin := Min(Min(R, G), B);\n  L := ( ((cMax + cMin) * HLSMAX) + RGBMAX ) / ( 2 * RGBMAX);\n  Luminance := Trunc(L);\n  if cMax = cMin then  { r=g=b --> achromatic case }\n  begin                \n    Hue := Trunc(HLSUndefined);\n    Saturation := 0;\n  end\n  else                 { chromatic case }\n  begin\n    { saturation }\n    if Luminance <= HLSMAX/2 then\n    begin\n      S := ( ((cMax-cMin)*HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin);\n    end\n      else\n    begin\n      S := ( ((cMax-cMin)*HLSMAX) + ((2*RGBMAX-cMax-cMin)/2) ) /\n           (2*RGBMAX-cMax-cMin);\n    end;\n\n    { hue }\n    Rdelta := Trunc(( ((cMax-R)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));\n    Gdelta := Trunc(( ((cMax-G)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));\n    Bdelta := Trunc(( ((cMax-B)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));\n    \n    if (Double(R) = cMax) then\n    begin\n      H := Bdelta - Gdelta\n    end\n    else if (Double(G) = cMax) then\n    begin\n      H := (HLSMAX/3) + Rdelta - Bdelta\n    end\n    else // B == cMax\n    begin\n      H := ((2 * HLSMAX) / 3) + Gdelta - Rdelta;\n    end;\n\n    if (H < 0) then\n      H := H + HLSMAX;\n    if (H > HLSMAX) then\n      H := H - HLSMAX;\n\n    Hue := Round(H);\n    Saturation := Trunc(S);\n  end;\nend;\n\nfunction HueToRGB(Lum, Sat, Hue: Double): Integer;\nvar\n  ResultEx: Double;\nbegin\n  { range check: note values passed add/subtract thirds of range }\n  if (hue < 0) then\n     hue := hue + HLSMAX;\n\n  if (hue > HLSMAX) then\n     hue := hue - HLSMAX;\n\n  { return r,g, or b value from this tridrant }\n  if (hue < (HLSMAX/6)) then\n    ResultEx := Lum + (((Sat-Lum)*hue+(HLSMAX/12))/(HLSMAX/6))\n  else if (hue < (HLSMAX/2)) then\n    ResultEx := Sat\n  else if (hue < ((HLSMAX*2)/3)) then\n    ResultEx := Lum + (((Sat-Lum)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6))\n  else\n    ResultEx := Lum;\n  Result := Round(ResultEx);\nend;\n\nfunction RoundColor(Value: Double): Integer;\nbegin\n  if Value > 255 then\n    Result := 255\n  else\n    Result := Round(Value);\nend;\n\nfunction RGB(R, G, B: Byte): Cardinal;\nbegin\n  Result := (Cardinal(R) or (Cardinal(G) shl 8) or (Cardinal(B) shl 16));\nend;\n\nfunction ColorHLSToRGB(Hue, Luminance, Saturation: Word): Cardinal;\nvar\n  R,G,B: Double;               { RGB component values }\n  Magic1,Magic2: Double;       { calculated magic numbers (really!) }\nbegin\n  if (Saturation = 0) then\n  begin            { achromatic case }\n     R := (Luminance * RGBMAX)/HLSMAX;\n     G := R;\n     B := R;\n     if (Hue <> HLSUndefined) then\n       ;{ ERROR }\n  end\n  else\n  begin            { chromatic case }\n     { set up magic numbers }\n     if (Luminance <= (HLSMAX/2)) then\n     begin\n       Magic2 := (Luminance * (HLSMAX + Saturation) + (HLSMAX/2)) / HLSMAX;\n     end\n       else\n     begin\n       Magic2 :=\n         Luminance + Saturation - ((Luminance * Saturation) +\n         (HLSMAX/2)) / HLSMAX;\n     end;\n     Magic1 := 2 * Luminance - Magic2;\n\n     { get RGB, change units from HLSMAX to RGBMAX }\n     R := (HueToRGB(Magic1,Magic2,Hue+(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX;\n     G := (HueToRGB(Magic1,Magic2,Hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;\n     B := (HueToRGB(Magic1,Magic2,Hue-(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX;\n  end;\n  Result := RGB(RoundColor(R), RoundColor(G), RoundColor(B));\nend;\n\nfunction LightenColor(RGB: Cardinal; Percentage: Integer): Cardinal;\nvar\n  H, S, L: Word; \nbegin\n  ColorRGBToHLS(RGB, H, L, S); \n  L := (Cardinal(L) * Percentage) div 100;\n  Result := ColorHLSToRGB(H, L, S); \nend;\n\nfunction GetSysColor(nIndex: Integer): DWORD;\n  external \'GetSysColor@User32.dll stdcall\';\n\nfunction ColorToRGB(Color: TColor): Cardinal;\nbegin\n  if Color < 0 then\n    Result := GetSysColor(Color and $000000FF) else\n    Result := Color;\nend;\n
Run Code Online (Sandbox Code Playgroud)\n

用法:

\n
LighterColor := TColor(LightenColor(ColorToRGB(Color), 150));\nDarkerColor := TColor(LightenColor(ColorToRGB(Color), 75));\n
Run Code Online (Sandbox Code Playgroud)\n

颜色较浅/较深

\n

参考:

\n\n