How to set the desktop color lazarus / 39-Graphics ---------------------------------------------------------------------- zxandris · 2024-12-08 18:55 Hello, I was wondering if anyone knows how to set the desktop color in windows please? Currently I have no idea how to do this.  I have a little routine that sets the desktop background, and I would really like to be able to set the desktop background color too. Any help would be gratefully appreciated CJ ---------------------------------------------------------------------- Fibonacci · 2024-12-08 23:24 How about that Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Windows, SysUtils, Classes; procedure set_desktopbg_solid_color(color: dword);const  bitmap = #$42#$4D#$3A#$00#$00#$00#$00#$00#$00#$00#$36#$00#$00#$00#$28#$00  +#$00#$00#$01#$00#$00#$00#$01#$00#$00#$00#$01#$00#$18#$00#$00#$00  +#$00#$00#$04#$00#$00#$00#$23#$2E#$00#$00#$23#$2E#$00#$00#$00#$00  +#$00#$00#$00#$00#$00#$00;var  temp: string;begin  with TMemoryStream.Create do begin    Write(bitmap[1], length(bitmap));    color := SwapEndian(color) shr 8;    Write(color, 4);    temp := ExtractFileDir(paramstr(0))+'\1x1.bmp';    SaveToFile(temp);    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @temp[1], SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);    DeleteFile(temp);    Free;  end;end; const  clRed = $0000FF;  clLime = $00FF00; begin  while true do begin    set_desktopbg_solid_color(clRed);    sleep(1000);    set_desktopbg_solid_color(clLime);    sleep(1000);  end;end. ---------------------------------------------------------------------- zxandris · 2024-12-08 23:27 Not entirely sure I'm reading this right but it appears that sets the wallpaper with a colored bitmap.  That is unfortunately definitely not what I want.  In control panel you can set the background color of the desktop seperately from the wallpaper.  That's what I'm trying to do. But thank you for the reply, and please do tell me if I'm not reading that right. CJ Quote from: Fibonacci on December 09, 2024, 12:24:59 amHow about that Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Windows, SysUtils, Classes; procedure set_desktopbg_solid_color(color: dword);const  bitmap = #$42#$4D#$3A#$00#$00#$00#$00#$00#$00#$00#$36#$00#$00#$00#$28#$00  +#$00#$00#$01#$00#$00#$00#$01#$00#$00#$00#$01#$00#$18#$00#$00#$00  +#$00#$00#$04#$00#$00#$00#$23#$2E#$00#$00#$23#$2E#$00#$00#$00#$00  +#$00#$00#$00#$00#$00#$00;var  temp: string;begin  with TMemoryStream.Create do begin    Write(bitmap[1], length(bitmap));    color := SwapEndian(color) shr 8;    Write(color, 4);    temp := ExtractFileDir(paramstr(0))+'\1x1.bmp';    SaveToFile(temp);    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @temp[1], SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);    DeleteFile(temp);    Free;  end;end; const  clRed = $0000FF;  clLime = $00FF00; begin  while true do begin    set_desktopbg_solid_color(clRed);    sleep(1000);    set_desktopbg_solid_color(clLime);    sleep(1000);  end;end. ---------------------------------------------------------------------- TRon · 2024-12-08 23:42 Quote from: zxandris on December 09, 2024, 12:27:51 amIn control panel you can set the background color of the desktop seperately from the wallpaper.  That's what I'm trying to do. Then do it in the same way but in code, see also these SO answers. There is a registry class. ---------------------------------------------------------------------- Fibonacci · 2024-12-08 23:50 Oh This color can be obtained by the DwmGetColorizationColor() function, but there is no Set variant of this function, so you need to do it through the registry ---------------------------------------------------------------------- zxandris · 2024-12-08 23:57 Okay from that link I came up with Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure SetDesktopColor(const clr : TColor);var   strColor : String;   r : TRegistry;begin      strColor := clrToRGBString(clr);      r := TRegistry.Create;      try         r.RootKey := HKEY_CURRENT_USER;       r.OpenKey('Control Panel\Colors\', false);         r.WriteString('Background', strColor);      finally        r.free;    end;      SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE);end;                                                                         Now it sets the registry key fine, but it doesn't actualy update the desktop color.  Would anyone know how to trigger windows into realising that's changed because I thought Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE);  Would do that, but it doesn't.  Now in further searching I found SetSysColors, but I don't have any reference for actually using this function.  Would anyone know how to use that perhaps.  Any help would be appreciated.  So far I've got a nice procedure that actually does set the color but it's not updating.  I assume that SetSysColors would do that, but honestly a nice call to refresh the desktop background somehow would be most excellent.  I am NOT very good with actual windows calls. lol CJ Quote from: TRon on December 09, 2024, 12:42:36 amQuote from: zxandris on December 09, 2024, 12:27:51 amIn control panel you can set the background color of the desktop seperately from the wallpaper.  That's what I'm trying to do. Then do it in the same way but in code, see also these SO answers. There is a registry class. ---------------------------------------------------------------------- zxandris · 2024-12-09 00:04 Code: [Select]int aElements[1] = {COLOR_BACKGROUND}; DWORD aNewColors[1]; aNewColors[0] = RGB(0x80, 0x00, 0x80);  // dark purple SetSysColors(1, aElements, aNewColors); Seems to be the c way of doing things but?? I don't know C I barely know pascal lol.  Anyone that could help would be very appreciated in converting that and making it perhaps so I can pass a TColor to be converted and set.  But I would guess I still have to notify windows of the update. ---------------------------------------------------------------------- TRon · 2024-12-09 00:12 Quote from: zxandris on December 09, 2024, 01:04:16 amSeems to be the c way of doing things Ah yes that seems to be a better approach, see also here and here According to that documentation a systemwide message is send so in theory the example should take care of things automatically. However, do note this: QuoteWindows 10 or greater: This value is not supported. ---------------------------------------------------------------------- zxandris · 2024-12-09 00:21 Okay so I really don't know how to send a windows message I think I found the message I want, but in this case Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, WM_SYSCOLORCHANGE); That doesn't work and frankly I'm pretty sure the first spi_ thing isn't the right one and for bonus points I'm actually on windows 11, so I'm really not sure if I got this right.  now if I got that right WM_ message I'm afraid I really don't know how to properly send it at all. Please help this poor fool   I've no experience in this sort of thing.  I've been programming pascal for years but recently it's come to my attention how much i DON'T know. CJ ---------------------------------------------------------------------- TRon · 2024-12-09 00:26 Well, keep in mind that for me personally windows is just a theory for me as I don't have/use it anymore (so unfortunately can't test either). ---------------------------------------------------------------------- zxandris · 2024-12-09 00:29 From what I can read that windows10+ is overly complicated to say the least, since the reg values are still there I would assume you can trigger something to make it refresh... it's quite frustrating you'd think this would be simple ---------------------------------------------------------------------- zxandris · 2024-12-09 00:40 Ok I think I'm getting closer but I know this doesn't work but I feel like it's close, so anyone that can correct me I'd love ya Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i SystemParametersInfo(WM_SYSCOLORCHANGE, 0, nil, WM_SETTINGCHANGE); ---------------------------------------------------------------------- Fibonacci · 2024-12-09 01:19 Got it. Now your turn - figure out the colors, create functions and share Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses SysUtils, Registry; function tohex(p: pointer; len: dword): string;var  i: integer;begin  result := '';  for i := 0 to len-1 do result += inttohex(pbyte(p+i)^, 2);end; function tobin(s: string): string;var  i: integer;begin  result := '';  i := 1;  while i < length(s) do begin    result += chr(strtoint('$'+copy(s, i, 2)));    inc(i, 2);  end;end; var  s: string; begin  with TRegistry.Create do begin    RootKey := HKEY_CURRENT_USER;    OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent', false);     // read    //setlength(s, 32);    //ReadBinaryData('AccentPalette', s[1], 32);    //writeln('palette = ', tohex(@s[1], length(s)));    //writeln('StartColorMenu = ', ReadInteger('StartColorMenu'));    //writeln('AccentColorMenu = ', ReadInteger('AccentColorMenu'));     // apply yellow    s := tobin('FF E8A800FFE08C00FFD35C00FFB90000BA890000805E00004D38000000B29400');    WriteBinaryData('AccentPalette', s[1], length(s));    WriteInteger('StartColorMenu', -16741958);    WriteInteger('AccentColorMenu', -16729601);     // apply green    //s := tobin('C1F7DD00A6F7D00068E3A80000CC6A000087460000522A00002B1600E300 8C00');    //WriteBinaryData('AccentPalette', s[1], length(s));    //WriteInteger('StartColorMenu', -12155136);    //WriteInteger('AccentColorMenu', -9778176);     Free;  end;end. Yellow: https://coolors.co/e8a800-e08c00-d35c00-b90000-890000-5e0000-380000- b29400 ---------------------------------------------------------------------- zxandris · 2024-12-09 01:34 I'm sorry but I have quite literally zero idea how to convert a TColor to a binary number that would work with that.  Also I might be misreading this but it sets the accent color which I may be wrong will only work if you're actually got the accent being set option by the desktop wallaper?? Quote from: Fibonacci on December 09, 2024, 02:19:38 amGot it. Now your turn - figure out the colors, create functions and share Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses SysUtils, Registry; function tohex(p: pointer; len: dword): string;var  i: integer;begin  result := '';  for i := 0 to len-1 do result += inttohex(pbyte(p+i)^, 2);end; function tobin(s: string): string;var  i: integer;begin  result := '';  i := 1;  while i < length(s) do begin    result += chr(strtoint('$'+copy(s, i, 2)));    inc(i, 2);  end;end; var  s: string; begin  with TRegistry.Create do begin    RootKey := HKEY_CURRENT_USER;    OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent', false);     // read    //setlength(s, 32);    //ReadBinaryData('AccentPalette', s[1], 32);    //writeln('palette = ', tohex(@s[1], length(s)));    //writeln('StartColorMenu = ', ReadInteger('StartColorMenu'));    //writeln('AccentColorMenu = ', ReadInteger('AccentColorMenu'));     // apply yellow    s := tobin('FF E8A800FFE08C00FFD35C00FFB90000BA890000805E00004D38000000B29400');    WriteBinaryData('AccentPalette', s[1], length(s));    WriteInteger('StartColorMenu', -16741958);    WriteInteger('AccentColorMenu', -16729601);     // apply green    //s := tobin('C1F7DD00A6F7D00068E3A80000CC6A000087460000522A00002B1600E300 8C00');    //WriteBinaryData('AccentPalette', s[1], length(s));    //WriteInteger('StartColorMenu', -12155136);    //WriteInteger('AccentColorMenu', -9778176);     Free;  end;end. Yellow: https://coolors.co/e8a800-e08c00-d35c00-b90000-890000-5e0000-380000- b29400 ---------------------------------------------------------------------- Fibonacci · 2024-12-09 01:42 Quote from: zxandris on December 09, 2024, 02:34:23 amI'm sorry but I have quite literally zero idea how to convert a TColor to a binary number that would work with that. You know HTML hex colors? RGB? TColor is the same, but in reverse, and with alpha channel byte. Look at the link to coolors.co, I put there all these colors but without the first byte (presumably the alpha channel). Quote from: zxandris on December 09, 2024, 02:34:23 amI might be misreading this but it sets the accent color which I may be wrong will only work if you're actually got the accent being set option by the desktop wallaper?? If thats not what you wanted then Im lost.. Run the code and see for yourself.