Recent

Author Topic: How to set the desktop color  (Read 737 times)

zxandris

  • Full Member
  • ***
  • Posts: 126
How to set the desktop color
« on: December 08, 2024, 07:55:47 pm »
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

  • Hero Member
  • *****
  • Posts: 643
  • Internal Error Hunter
Re: How to set the desktop color
« Reply #1 on: December 09, 2024, 12:24:59 am »
How about that :D

Code: Pascal  [Select][+][-]
  1. uses Windows, SysUtils, Classes;
  2.  
  3. procedure set_desktopbg_solid_color(color: dword);
  4. const
  5.   bitmap = #$42#$4D#$3A#$00#$00#$00#$00#$00#$00#$00#$36#$00#$00#$00#$28#$00
  6.   +#$00#$00#$01#$00#$00#$00#$01#$00#$00#$00#$01#$00#$18#$00#$00#$00
  7.   +#$00#$00#$04#$00#$00#$00#$23#$2E#$00#$00#$23#$2E#$00#$00#$00#$00
  8.   +#$00#$00#$00#$00#$00#$00;
  9. var
  10.   temp: string;
  11. begin
  12.   with TMemoryStream.Create do begin
  13.     Write(bitmap[1], length(bitmap));
  14.     color := SwapEndian(color) shr 8;
  15.     Write(color, 4);
  16.     temp := ExtractFileDir(paramstr(0))+'\1x1.bmp';
  17.     SaveToFile(temp);
  18.     SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @temp[1], SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);
  19.     DeleteFile(temp);
  20.     Free;
  21.   end;
  22. end;
  23.  
  24. const
  25.   clRed = $0000FF;
  26.   clLime = $00FF00;
  27.  
  28. begin
  29.   while true do begin
  30.     set_desktopbg_solid_color(clRed);
  31.     sleep(1000);
  32.     set_desktopbg_solid_color(clLime);
  33.     sleep(1000);
  34.   end;
  35. end.

zxandris

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #2 on: December 09, 2024, 12:27:51 am »
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

How about that :D

Code: Pascal  [Select][+][-]
  1. uses Windows, SysUtils, Classes;
  2.  
  3. procedure set_desktopbg_solid_color(color: dword);
  4. const
  5.   bitmap = #$42#$4D#$3A#$00#$00#$00#$00#$00#$00#$00#$36#$00#$00#$00#$28#$00
  6.   +#$00#$00#$01#$00#$00#$00#$01#$00#$00#$00#$01#$00#$18#$00#$00#$00
  7.   +#$00#$00#$04#$00#$00#$00#$23#$2E#$00#$00#$23#$2E#$00#$00#$00#$00
  8.   +#$00#$00#$00#$00#$00#$00;
  9. var
  10.   temp: string;
  11. begin
  12.   with TMemoryStream.Create do begin
  13.     Write(bitmap[1], length(bitmap));
  14.     color := SwapEndian(color) shr 8;
  15.     Write(color, 4);
  16.     temp := ExtractFileDir(paramstr(0))+'\1x1.bmp';
  17.     SaveToFile(temp);
  18.     SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, @temp[1], SPIF_UPDATEINIFILE or SPIF_SENDWININICHANGE);
  19.     DeleteFile(temp);
  20.     Free;
  21.   end;
  22. end;
  23.  
  24. const
  25.   clRed = $0000FF;
  26.   clLime = $00FF00;
  27.  
  28. begin
  29.   while true do begin
  30.     set_desktopbg_solid_color(clRed);
  31.     sleep(1000);
  32.     set_desktopbg_solid_color(clLime);
  33.     sleep(1000);
  34.   end;
  35. end.

TRon

  • Hero Member
  • *****
  • Posts: 3750
Re: How to set the desktop color
« Reply #3 on: December 09, 2024, 12:42:36 am »
In 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.
I do not have to remember anything anymore thanks to total-recall.

Fibonacci

  • Hero Member
  • *****
  • Posts: 643
  • Internal Error Hunter
Re: How to set the desktop color
« Reply #4 on: December 09, 2024, 12:50:18 am »
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

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #5 on: December 09, 2024, 12:57:01 am »
Okay from that link I came up with

Code: Pascal  [Select][+][-]
  1. procedure SetDesktopColor(const clr : TColor);
  2. var
  3.    strColor : String;
  4.    r : TRegistry;
  5. begin
  6.       strColor := clrToRGBString(clr);
  7.       r := TRegistry.Create;
  8.       try
  9.          r.RootKey := HKEY_CURRENT_USER;
  10.          r.OpenKey('Control Panel\Colors\', false);
  11.          r.WriteString('Background', strColor);
  12.       finally
  13.         r.free;
  14.       end;
  15.       SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE);
  16. 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][+][-]
  1.       SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, nil, SPIF_SENDWININICHANGE);
  2.  

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


In 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

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #6 on: December 09, 2024, 01:04:16 am »
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

  • Hero Member
  • *****
  • Posts: 3750
Re: How to set the desktop color
« Reply #7 on: December 09, 2024, 01:12:25 am »
Seems 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:
Quote
Windows 10 or greater: This value is not supported.
« Last Edit: December 09, 2024, 01:15:28 am by TRon »
I do not have to remember anything anymore thanks to total-recall.

zxandris

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #8 on: December 09, 2024, 01:21:25 am »
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][+][-]
  1. 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

  • Hero Member
  • *****
  • Posts: 3750
Re: How to set the desktop color
« Reply #9 on: December 09, 2024, 01:26:21 am »
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).
I do not have to remember anything anymore thanks to total-recall.

zxandris

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #10 on: December 09, 2024, 01:29:44 am »
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

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #11 on: December 09, 2024, 01:40:00 am »
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][+][-]
  1. SystemParametersInfo(WM_SYSCOLORCHANGE, 0, nil, WM_SETTINGCHANGE);

Fibonacci

  • Hero Member
  • *****
  • Posts: 643
  • Internal Error Hunter
Re: How to set the desktop color
« Reply #12 on: December 09, 2024, 02:19:38 am »
Got it. Now your turn - figure out the colors, create functions and share ;)

Code: Pascal  [Select][+][-]
  1. uses SysUtils, Registry;
  2.  
  3. function tohex(p: pointer; len: dword): string;
  4. var
  5.   i: integer;
  6. begin
  7.   result := '';
  8.   for i := 0 to len-1 do result += inttohex(pbyte(p+i)^, 2);
  9. end;
  10.  
  11. function tobin(s: string): string;
  12. var
  13.   i: integer;
  14. begin
  15.   result := '';
  16.   i := 1;
  17.   while i < length(s) do begin
  18.     result += chr(strtoint('$'+copy(s, i, 2)));
  19.     inc(i, 2);
  20.   end;
  21. end;
  22.  
  23. var
  24.   s: string;
  25.  
  26. begin
  27.   with TRegistry.Create do begin
  28.     RootKey := HKEY_CURRENT_USER;
  29.     OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent', false);
  30.  
  31.     // read
  32.     //setlength(s, 32);
  33.     //ReadBinaryData('AccentPalette', s[1], 32);
  34.     //writeln('palette = ', tohex(@s[1], length(s)));
  35.     //writeln('StartColorMenu = ', ReadInteger('StartColorMenu'));
  36.     //writeln('AccentColorMenu = ', ReadInteger('AccentColorMenu'));
  37.  
  38.     // apply yellow
  39.     s := tobin('FFE8A800FFE08C00FFD35C00FFB90000BA890000805E00004D38000000B29400');
  40.     WriteBinaryData('AccentPalette', s[1], length(s));
  41.     WriteInteger('StartColorMenu', -16741958);
  42.     WriteInteger('AccentColorMenu', -16729601);
  43.  
  44.     // apply green
  45.     //s := tobin('C1F7DD00A6F7D00068E3A80000CC6A000087460000522A00002B1600E3008C00');
  46.     //WriteBinaryData('AccentPalette', s[1], length(s));
  47.     //WriteInteger('StartColorMenu', -12155136);
  48.     //WriteInteger('AccentColorMenu', -9778176);
  49.  
  50.     Free;
  51.   end;
  52. end.



Yellow:
https://coolors.co/e8a800-e08c00-d35c00-b90000-890000-5e0000-380000-b29400
« Last Edit: December 09, 2024, 02:32:19 am by Fibonacci »

zxandris

  • Full Member
  • ***
  • Posts: 126
Re: How to set the desktop color
« Reply #13 on: December 09, 2024, 02:34:23 am »
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??

Got it. Now your turn - figure out the colors, create functions and share ;)

Code: Pascal  [Select][+][-]
  1. uses SysUtils, Registry;
  2.  
  3. function tohex(p: pointer; len: dword): string;
  4. var
  5.   i: integer;
  6. begin
  7.   result := '';
  8.   for i := 0 to len-1 do result += inttohex(pbyte(p+i)^, 2);
  9. end;
  10.  
  11. function tobin(s: string): string;
  12. var
  13.   i: integer;
  14. begin
  15.   result := '';
  16.   i := 1;
  17.   while i < length(s) do begin
  18.     result += chr(strtoint('$'+copy(s, i, 2)));
  19.     inc(i, 2);
  20.   end;
  21. end;
  22.  
  23. var
  24.   s: string;
  25.  
  26. begin
  27.   with TRegistry.Create do begin
  28.     RootKey := HKEY_CURRENT_USER;
  29.     OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent', false);
  30.  
  31.     // read
  32.     //setlength(s, 32);
  33.     //ReadBinaryData('AccentPalette', s[1], 32);
  34.     //writeln('palette = ', tohex(@s[1], length(s)));
  35.     //writeln('StartColorMenu = ', ReadInteger('StartColorMenu'));
  36.     //writeln('AccentColorMenu = ', ReadInteger('AccentColorMenu'));
  37.  
  38.     // apply yellow
  39.     s := tobin('FFE8A800FFE08C00FFD35C00FFB90000BA890000805E00004D38000000B29400');
  40.     WriteBinaryData('AccentPalette', s[1], length(s));
  41.     WriteInteger('StartColorMenu', -16741958);
  42.     WriteInteger('AccentColorMenu', -16729601);
  43.  
  44.     // apply green
  45.     //s := tobin('C1F7DD00A6F7D00068E3A80000CC6A000087460000522A00002B1600E3008C00');
  46.     //WriteBinaryData('AccentPalette', s[1], length(s));
  47.     //WriteInteger('StartColorMenu', -12155136);
  48.     //WriteInteger('AccentColorMenu', -9778176);
  49.  
  50.     Free;
  51.   end;
  52. end.



Yellow:
https://coolors.co/e8a800-e08c00-d35c00-b90000-890000-5e0000-380000-b29400

Fibonacci

  • Hero Member
  • *****
  • Posts: 643
  • Internal Error Hunter
Re: How to set the desktop color
« Reply #14 on: December 09, 2024, 02:42:15 am »
I'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).

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??

If thats not what you wanted then Im lost.. Run the code and see for yourself.

 

TinyPortal © 2005-2018