C# [API] Gets the Windows 10 Accent Colors

  1 namespace ABI {
  2     namespace Windows {
  3         namespace UI {
  4             namespace ViewManagement {
  5                 enum UIColorType : int {
  6                     UIColorType_Background = 0,
  7                     UIColorType_Foreground = 1,
  8                     UIColorType_AccentDark3 = 2,
  9                     UIColorType_AccentDark2 = 3,
 10                     UIColorType_AccentDark1 = 4,
 11                     UIColorType_Accent = 5,
 12                     UIColorType_AccentLight1 = 6,
 13                     UIColorType_AccentLight2 = 7,
 14                     UIColorType_AccentLight3 = 8,
 15                     UIColorType_Complement = 9,
 16                 };
 17 
 18                 struct Color {
 19                     public byte A;
 20                     public byte R;
 21                     public byte G;
 22                     public byte B;
 23                 };
 24 
 25                 struct COLORREF {
 26                     public byte wRed;
 27                     public byte wGreen;
 28                     public byte wBlue;
 29                     public byte wReserved;
 30                 }
 31 
 32                 unsafe class Util {
 33                     const string WINADVAPI = "advapi32.dll";
 34                     const string WINBASEAPI = "kernel32.dll";
 35 
 36                     public static uint ARGB(byte a, byte r, byte g, byte b) {
 37                         return (uint)(a << 24 | r << 16 | g << 8 | b);
 38                     }
 39 
 40                     #region heapapi.h
 41                     [DllImport(WINBASEAPI)]
 42                     public static extern
 43                     void*
 44                     GetProcessHeap(
 45                         );
 46 
 47                     [DllImport(WINBASEAPI)]
 48                     public static extern
 49                     void*
 50                     HeapAlloc(
 51                         [In] void* hHeap,
 52                         [In] uint dwFlags,
 53                         [In] void* dwBytes
 54                         );
 55 
 56                     [DllImport(WINBASEAPI)]
 57                     public static extern
 58                     int
 59                     HeapFree(
 60                         [In, Out] void* hHeap,
 61                         [In] uint dwFlags,
 62                         [Optional] void* lpMem
 63                         );
 64                     #endregion
 65 
 66                     #region winreg.h
 67 
 68                     const int REG_KEYNAME_LIMITS_CHARS = 0xff;
 69                     const int REG_KEYNAME_LIMITS_BYTES = REG_KEYNAME_LIMITS_CHARS << 1;
 70 
 71                     const int REG_VALUENAME_LIMITS_CHARS = 0x3fff;
 72                     const int REG_VALUENAME_LIMITS_BYTES = REG_VALUENAME_LIMITS_CHARS << 1;
 73 
 74                     [DllImport(WINADVAPI)]
 75                     public static extern
 76                     int
 77                     RegCloseKey(
 78                         [In] void* hKey
 79                         );
 80 
 81                     [DllImport(WINADVAPI, CharSet = (CharSet)3)]
 82                     public static extern
 83                     int
 84                     RegGetValueW(
 85                         [In] void* hkey,
 86                         [In, Optional] string lpSubKey,
 87                         [In, Optional] string lpValue,
 88                         [In] /*_In_*/ uint dwFlags,
 89                         [Out, Optional] uint* pdwType,
 90                         [Out, Optional] void* pvData,
 91                         [In, Out, Optional] uint* pcbData
 92                         );
 93 
 94                     [DllImport(WINADVAPI, CharSet = (CharSet)3)]
 95                     public static extern
 96                     int
 97                     RegOpenKeyW(
 98                         [In] void* hKey,
 99                         [In, Optional] string lpSubKey,
100                         [Out] void** phkResult
101                         );
102 
103                     [DllImport(WINADVAPI, CharSet = (CharSet)3)]
104                     public static extern
105                     int
106                     RegQueryValueExW(
107                         [In] void* hKey,
108                         [In, Optional] string lpValueName,
109                         uint* lpReserved,
110                         [Out, Optional] uint* lpType,
111                         [Out, Optional] byte* lpData,
112                         uint* lpcbData
113                         );
114                     #endregion
115                 }
116 
117                 unsafe class UISettings {
118                     public static int IsSystemUsesLightTheme {
119                         get {
120                             /* Key:
121                              *  HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize
122                              * Value:
123                              *  SystemUsesLightTheme
124                              * Type:
125                              *  REG_DWORD
126                              */
127                             const string REG_KEY_PERSONALIZE = "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
128 
129                             uint dwType = REG_DWORD;
130                             uint dwData;
131                             uint cbData = sizeof(uint);
132                             int e = RegGetValueW((void*)HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "SystemUsesLightTheme", RRF_RT_DWORD, &dwType, &dwData, &cbData);
133                             if (e != 0) return 0;
134                             return (int)dwData;
135                         }
136                     }
137 
138                     public static int GetColorValue(UIColorType desiredColor, Color* value) {
139                         /* 
140                          * Windows 10 Accent Colors
141                          * Key:
142                          *  Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Accent
143                          * Value:
144                          *  AccentPalette
145                          * Type:
146                          *  REG_BINARY
147                          */
148 
149                         const string REG_KEY_EXPLORER_ACCENT = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent";
150                         const string REG_VALUE_ACCENTPALETTE = "AccentPalette";
151 
152                         int fret = 0;
153                         int iret = -1;
154                         uint dwType;
155                         uint cbData;
156                         void* hHeap = GetProcessHeap();
157                         void* hkey = null;
158                         void* pDataSeq = null;
159                         void* pDataInv = null;
160                         COLORREF* pclr;
161 
162                         if (value == null) return 0;
163 
164                         iret = RegOpenKeyW((void*)HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent", &hkey);
165                         if (iret != 0) goto x;
166 
167                         iret = RegQueryValueExW(hkey, "AccentPalette", null, &dwType, null, &cbData);
168                         if (iret != 0) goto x;
169 
170                         pDataSeq = HeapAlloc(hHeap, 0u, (void*)cbData);
171                         iret = RegQueryValueExW(hkey, "AccentPalette", null, &dwType, (byte*)pDataSeq, &cbData);
172                         if (iret != 0) goto x;
173 
174                         pDataInv = HeapAlloc(hHeap, 0u, (void*)cbData);
175                         int ilen = (int)cbData / sizeof(COLORREF);
176                         COLORREF* pclrseq = (COLORREF*)pDataSeq + ilen - 2;
177                         COLORREF* pclrinv = (COLORREF*)pDataInv;
178                         for (int i = 0; i < ilen; i++) {
179                             *pclrinv++ = *pclrseq--;
180                         }
181                         *((COLORREF*)pDataInv + ilen - 1) = *((COLORREF*)pDataSeq + ilen - 1);
182 
183                         switch (desiredColor) {
184                             case UIColorType.UIColorType_Background: {
185                                 if (IsSystemUsesLightTheme != 0) {
186                                     *(uint*)value = 0xffffffff;
187                                 } else {
188                                     *(uint*)value = 0x000000ff;
189                                 }
190                                 break;
191                             }
192                             case UIColorType.UIColorType_Foreground: {
193                                 if (IsSystemUsesLightTheme != 0) {
194                                     *(uint*)value = 0x000000ff;
195                                 } else {
196                                     *(uint*)value = 0xffffffff;
197                                 }
198                                 break;
199                             }
200                             default: {
201                                 pclr = ((COLORREF*)pDataInv + (int)desiredColor - 2);
202                                 value->A = pclr->wReserved;
203                                 value->R = pclr->wRed;
204                                 value->G = pclr->wGreen;
205                                 value->B = pclr->wBlue;
206                                 break;
207                             }
208                         }
209                         fret = 1;
210 
211                     x:
212                         if (pDataInv != null) HeapFree(hHeap, 0u, pDataInv);
213                         if (pDataSeq != null) HeapFree(hHeap, 0u, pDataSeq);
214                         if (hkey != null) RegCloseKey(hkey);
215                         return fret;
216                     }
217                 }
218             }
219         }
220     }
221 }

 

 1         unsafe static int Main(string[] args) {
 2             ABI.Windows.UI.ViewManagement.Color clra;
 3             System.Drawing.Color clrs;
 4             foreach (var item in typeof(ABI.Windows.UI.ViewManagement.UIColorType).GetEnumValues()) {
 5                 ABI.Windows.UI.ViewManagement.UISettings.GetColorValue((ABI.Windows.UI.ViewManagement.UIColorType)item, &clra);
 6                 clrs = System.Drawing.Color.FromArgb(clra.A, clra.R, clra.G, clra.B);
 7                 Console.WriteLine($"{item} : 0x{ARGB(clra.A, clra.R, clra.G, clra.B):x2} {clrs}");
 8             }
 9             return 0;
10         }

 

C# [API] Gets the Windows 10 Accent Colors

上一篇:Windows and Dos


下一篇:WPF之命令