C++怎么获取系统主题颜色?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++怎么获取系统主题颜色?相关的知识,希望对你有一定的参考价值。

我想取到win8边框的颜色,C++怎么做?开发环境VS2012
我要获取的就是这个颜色。(vista以上系统)

我有一个编程书里有说这一点,可我搞不懂,我把文件传给你吧
typedef struct UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; WNDCLASSEX, *PWNDCLASSEX; 成员介绍 cbSize 值为sizeof(WNDCLASSEX),在调用GetClassInfoEx前必须要先设置它值。
style 窗口类的样式,它的值可以是窗口样式值的任意组合。
可以有以下的值
lpfnWndProc 指向窗口处理函数(回调函数)。处理窗口事件,像单击鼠标会怎样,右击鼠标会怎样,都是由此函数控制的。
cbClsExtra 为窗口类的额外信息做记录,系统初始化为0。
cbWndExtra 记录窗口实例的额外信息,系统初始为0.如果程序使用WNDCLASSEX注册一个从资源文件里创建的对话框,则此参数必须设置为DLGWINDOWEXTRA
hIcon 窗口类的图标,为资源句柄,如果设置为NULL,系统将为窗口提供一个默认的图标。
hCursor 窗口类的鼠标样式,为鼠标样式资源的句柄,如果设置为NULL,系统提供一个默认的鼠标样式。
hbrBackground 窗口类的背景刷,为背景刷句柄,也可以为系统颜色值,如果颜色值已给出,则必须转化为以下的HBRUSH的值
COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT
lpszMenuName 指向一个以NULL结尾的字符床,同目录资源的名字一样。如果使用整型id表示菜单,可以用MAKEINTRESOURCE定义一个宏。如果它的值为NULL,那么该类创建的窗口将都没有默认的菜单。
lpszClassName 窗口类的名字,字符串类型。
hIconSm 小图标的句柄,在任务栏显示的图标,可以和上面的那个一样。

定义一个WNDCLASSEX类型变量后,在给变量成员初始化后,我们就可以用
RegisterWindowEx(&wndclassex)来注册这个窗口类了。

这个注册过程,就和我们平常创建一个项目一样,都要先注册才能创建 。

创建窗口
这一步很简单,就是利用CreateWindowEx()函数来创建就是了。
CreateWindowEx函数的原型如下:
HWND CreateWindowEx(

DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); 参数说明 dwExStyle:指定窗口的扩展风格。该参数可以是下列值:
WS_EX_ACCEPTFILES:指定以该风格创建的窗口接受一个拖拽文件。
   WS_EX_APPWINDOW:当窗口可见时,将一个顶层窗口放置到任务条上。
   WS_EX_CLIENTEDGE:指定窗口有一个带阴影的边界。
   WS_EX_CONTEXTHELP:在窗口的标题条包含一个问号标志。

WS_EX_CONTROLPARENT:允许用户使用Tab键在窗口的子窗口间搜索。
   WS_EX_DLGMODALFRAME:创建一个带双边的窗口;该窗口可以在dwStyle中指定WS_CAPTION风格来创建一个标题栏。
   WS_EX_LEFT:窗口具有左对齐属性,这是缺省设置的。
   WS_EX_LEFTSCROLLBAR:如果外壳语言是如Hebrew,Arabic,或其他支持reading order alignment的语言,则标题条(如果存在)则在客户区的左部分。若是其他语言,在该风格被忽略并且不作为错误处理。
   WS_EX_LTRREADING:窗口文本以LEFT到RIGHT(自左向右)属性的顺序显示。这是缺省设置的。
   WS_EX_MDICHILD:创建一个MD子窗口。
  WS_EX_NOPATARENTNOTIFY:指明以这个风格创建的窗口在被创建和销毁时不向父窗口发送WM_PARENTNOTFY消息。
WS_EX_OVERLAPPED:WS_EX_CLIENTEDGEWS_EX_WINDOWEDGE的组合。
WS_EX_PALETTEWINDOW:WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW和WS_WX_TOPMOST风格的组合WS_EX_RIGHT:窗口具有普通的右对齐属性,这依赖于窗口类。

WS_EX_RIGHTSCROLLBAR:垂直滚动条在窗口的右边界。这是缺省设置的。
   WS_EX_RTLREADING:如果外壳语言是如Hebrew,Arabic,或其他支持读顺序对齐(reading order alignment)的语言,则窗口文本是一自左向右)RIGHT到LEFT顺序的读出顺序。

WS_EX_STATICEDGE:为不接受用户输入的项创建一个3一维边界风格
  WS_EX_TOOLWIDOW:创建工具窗口,即窗口是一个游动的工具条。

WS_EX_TOPMOST:指明以该风格创建的窗口应放置在所有非最高层窗口的上面并且停留在其L,即使窗口未被激活。使用函数SetWindowPos来设置和移去这个风格。
   WS_EX_TRANSPARENT:指定以这个风格创建的窗口在窗口下的同属窗口已重画时,该窗口才可以重画。
  由于其下的同属富日已被重画,该窗口是透明的。

IpClassName: 窗口类的名字。
lpWindowName:指向一个指定窗口名的空结束的字符串指针。其实就是窗口的名字。
dwStyle:指定创建窗口的风格。该参数可以是下列窗口风格的组合再加上说明部分的控制风格。
x:窗口的横坐标。
y:窗口的竖坐标。
nWidth:窗口的宽度。
nHeight:窗口的高度。
hMenu:菜单句柄,或依据窗口风格指明一个子窗口标识。
hlnstance:与窗口相关联的模块事例的句柄。
lpParam:指向一个值的指针,该值传递给窗口 WM_CREATE消息
返回值:如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。

显示窗口
显示窗口就是更简单的事情了。
连个函数轻松搞定,第一个函数就是ShowWindow(),原型如下:
BOOL ShowWindow(

HWND hWnd,//当前的窗口句柄 int nCmdShow //可见状态 ); 因为CreateWindowEx函数创建的窗口是在内存中的,并没有显示到显示器上,用ShowWindow()函数,设定窗口的可见状态,并把数据从内存中移动到显卡上,以便显示。 第二个函数就是UpdateWindow();追问

嗯。i@yenkn.com

追答

我没这个网,我补充了

参考技术A

可以用这个 API

DWMAPI DwmGetColorizationColor(
  DWORD *pcrColorization,
  BOOL  *pfOpaqueBlend
);

有专门说明这个 API 的博客 CSDN

以下摘自Microsoft doc

Parameters

pcrColorization

A pointer to a value that, when this function returns successfully,
receives the current color used for glass composition. The color format
of the value is 0xAARRGGBB.

pfOpaqueBlend

A pointer to a value that, when this function returns successfully, indicates whether the color is an opaque blend. TRUE if the color is an opaque blend; otherwise, FALSE.

Return Value

If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

参考技术B winuser.h头文件中有所有系统颜色的宏定义,不妨在这里找您要的颜色:

/*
* Color Types
*/
#define CTLCOLOR_MSGBOX 0
#define CTLCOLOR_EDIT 1
#define CTLCOLOR_LISTBOX 2
#define CTLCOLOR_BTN 3
#define CTLCOLOR_DLG 4
#define CTLCOLOR_SCROLLBAR 5
#define CTLCOLOR_STATIC 6
#define CTLCOLOR_MAX 7
#define COLOR_SCROLLBAR 0
#define COLOR_BACKGROUND 1
#define COLOR_ACTIVECAPTION 2
#define COLOR_INACTIVECAPTION 3
#define COLOR_MENU 4
#define COLOR_WINDOW 5
#define COLOR_WINDOWFRAME 6
#define COLOR_MENUTEXT 7
#define COLOR_WINDOWTEXT 8
#define COLOR_CAPTIONTEXT 9
#define COLOR_ACTIVEBORDER 10
#define COLOR_INACTIVEBORDER 11
#define COLOR_APPWORKSPACE 12
#define COLOR_HIGHLIGHT 13
#define COLOR_HIGHLIGHTTEXT 14
#define COLOR_BTNFACE 15
#define COLOR_BTNSHADOW 16
#define COLOR_GRAYTEXT 17
#define COLOR_BTNTEXT 18
#define COLOR_INACTIVECAPTIONTEXT 19
#define COLOR_BTNHIGHLIGHT 20
#if(WINVER >= 0x0400)
#define COLOR_3DDKSHADOW 21
#define COLOR_3DLIGHT 22
#define COLOR_INFOTEXT 23
#define COLOR_INFOBK 24
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define COLOR_HOTLIGHT 26
#define COLOR_GRADIENTACTIVECAPTION 27
#define COLOR_GRADIENTINACTIVECAPTION 28
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0400)
#define COLOR_DESKTOP COLOR_BACKGROUND
#define COLOR_3DFACE COLOR_BTNFACE
#define COLOR_3DSHADOW COLOR_BTNSHADOW
#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT
#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT
#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT
#endif /* WINVER >= 0x0400 */

调用DWORD GetSysColor(int nIndex);函数,可以返回颜色的RGB值。追问

你假如是vista以上系统的话,右键个性化-颜色 有很多颜色选,我要获取的就是那个颜色。

追答

没用过vista不好意思,你不妨记录下它的RBG值直接写到程序里啊

本回答被提问者和网友采纳
参考技术C 我也一直在找这个问题的方法,现在终于找到答案了。使用DwmGetColorizationParameters函数可以实现楼主的需求,函数的使用方法请参照微软MSDN。另外WM_DWMCOLORIZATIONCOLORCHANGED消息可以响应主题颜色改变。
需要注意的是,DwmGetColorizationParameters获取到的颜色不是COLORREF类型,而是0xAARRGGBB,需要做一个简单的转换。

Windows 10 应用开发跟随系统主题颜色

有些时候,希望应用程序中的某些颜色可以与系统的主题颜色相同,并且当系统主题色改变时进行同步。

实现过程并不复杂,主要用到 UISettings 类,它公开一个 GetColorValue 方法,访问这个方法,可以得到指定的颜色值(用Color结构表示)。而表示要获取颜色的类型由一个叫 UIColorType 的枚举来约定。如下面超高清截图所示。

可能有朋友在调用 GetColorValue 方法时会使用值 Background,其实这个值不是系统主题色,是窗口的背景色,默认情况返回的都是白色。系统主题色是值 Accent (即所谓的强调色)。

另外大伙会看到好N个以 Accent 开头的值,如 AccentDark1、AccentLight2等。这些值的意思就是,在 Accent 值的基础上加深或者浅化。比如,Accent 值返回蓝色,那么,AccentLight1 表示相对于 Accent 值稍浅一点的蓝色;AccentLight2 再浅一点;AccentLight3 再再浅一点。至于说浅多少,深多少,这个你自己研究研究吧。

下面给大伙看看实测效果,为了雅观,先弄个UI。

        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <Rectangle Name="rect" Width="300" Height="250" Margin="15" Stroke="Red" StrokeThickness="3"/>
            <TextBlock Margin="12" Grid.Row="1" Text="注意看上面的矩形。" FontSize="16"/>
        </Grid>

这段 XAML 不复杂,要是看不懂的话,可以去咨询济公。主要的元素是那个矩形,待会咱们让它的填充颜色跟随系统的主题色。

那么,有大伙伴会问了,当系统主题色更改后,我的应用怎么得到通知呢?别紧张,君不见,UISettings 类有个 ColorValuesChanged 事件吗,这就对了,如果系统主题色改变,就会引发这个事件。所以,聪明的你一定知道后面的思路了,对,就是响应这个事件,给填充矩形的画刷改变颜色即可。

不过,有一点你得严重注意,这个事件是在另一个线程上调用的,所以,你要访问 UI 元素的话,不要忘了带上 Dispatcher。

比如这样。

     uisetting = new UISettings();
     uisetting.ColorValuesChanged += OnColorValuesChanged;

        private async void OnColorValuesChanged(UISettings sender, object args)
        {
            Color bg, fg;
            bg = sender.GetColorValue(UIColorType.Accent);
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                () =>
                {
                    SolidColorBrush brush = rect.Fill as SolidColorBrush;
                    if (brush == null)
                    {
                        brush = new SolidColorBrush();
                    }
                    brush.Color = bg;
                });
        }

 

代码很 Easy,但效果很性感。不信你试试。

 

是不是很性感呢?

 

程序代码下载地址

 

以上是关于C++怎么获取系统主题颜色?的主要内容,如果未能解决你的问题,请参考以下文章

visualstudio命令提示符颜色怎么改

JetPack Compose 主题配色太少怎么办? 来设计自己的颜色系统吧

win10状态栏右键菜单变成黑色怎么破

android studio黑色主题怎么设置字体颜色

手机字体颜色怎么更改?

TailwindCSS - 在“浅色”、“深色”或“系统设置”之间切换颜色主题