每一个C#的Winform项目的Main方法里,都有这么一行代码,那么它究竟是用来做什么的呢?

Application.EnableVisualStyles();

从注释来看,这是一行用作设置样式的代码,那么它究竟设置了哪些样式呢?

源码浅析

public static void EnableVisualStyles() {
string assemblyLoc = null; // SECREVIEW : This Assert is ok, getting the module path is a safe operation,
// the result is provided by the system.
//
FileIOPermission fiop = new FileIOPermission(PermissionState.None);
fiop.AllFiles = FileIOPermissionAccess.PathDiscovery;
fiop.Assert();
try {
assemblyLoc = typeof(Application).Assembly.Location;
}
finally {
CodeAccessPermission.RevertAssert();
}
// Pull manifest from our resources
if (assemblyLoc != null) {
EnableVisualStylesInternal(assemblyLoc, 101);
}
}

从代码来看,最关键的也就是最后那句

EnableVisualStylesInternal(assemblyLoc, 101);

在这句代码里,将本地GAC_MSIL文件夹里的System.Windows.Forms.dll路径和一个“101”传了进去,用于设置所谓的样式。

当我们进入到CreateActivationContext方法里后,会看到如下代码:

[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
public static bool CreateActivationContext(string dllPath, int nativeResourceManifestID)
{
lock (typeof(ThemingScope))
{
if (!contextCreationSucceeded && OSFeature.Feature.IsPresent(OSFeature.Themes))
{ enableThemingActivationContext = new ACTCTX(); enableThemingActivationContext.cbSize = Marshal.SizeOf(typeof(ACTCTX));
enableThemingActivationContext.lpSource = dllPath;
enableThemingActivationContext.lpResourceName = (IntPtr)nativeResourceManifestID;
enableThemingActivationContext.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; hActCtx = CreateActCtx(ref enableThemingActivationContext);
contextCreationSucceeded = (hActCtx != new IntPtr(-1));
} return contextCreationSucceeded;
}
}

在设置了一通ACTCTX的属性后,将它传入了CreateActCtx方法内,用于创建ActivationContext。

而那个“101”则被赋值给了lpResourceName ,那么我们如果想搞懂那个“101”是做什么的,就要先看懂lpResourceName 是什么意思。

在微软官方文档里找到了答案:

ACTCTXA结构

在这里我们可以看到lpResourceName指的是和dll或者exe同级目录的资源,接下来我们只需要用vs打开一下上文提到的dll,就可以真相大白了。

这下我们明白了,所谓的资源就是清单文件(manifest文件),也就是说这个所谓的EnableVisualStyles方法其实设置的并不是我们常规意义上的样式,而是设置的程序应用信息,比如引用dll、注册路径、版本号等。

这是清单文件的内容。

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<description>Windows Forms Common Control manifest</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
</assembly>

从这里我们可以看到,这里映射到了name叫“Microsoft.Windows.Common-Controls”的文件夹,果不其然,我在C:\Windows\WinSxS找到了它。

这里可以看到版本号也是一致的,接下来我们看一下里面记录的哪些东西?

随机点开一个

看到这里我们就明白了,这个 comctl32.dll里面记录的是一些常用的图标之类的资源文件,而这个Application.EnableVisualStyles();设置的也是这些。

浅析Winform的可视样式的更多相关文章

  1. Winform自定义窗体样式,实现标题栏可灵活自定义

    最近在编写C/S结构应用程序时,感觉窗体的标题栏样式太死板了,标题文字不能更改大小.颜色.字体等,按钮不能隐藏等问题,在网上也查找了许多相关的资料,没有找到合适的解决方案,发现许多人也在寻求这个问题, ...

  2. winform npoi excel 样式设置

    IWorkbook excel = new HSSFWorkbook();//创建.xls文件 ISheet sheet = excel.CreateSheet("sheet1") ...

  3. 浅析WINFORM工具条的重用实现

    一直以来,我都想看看别人家的工具栏重用(图1)到底是如何实现的,但在网上搜索了很久都没有找到过,即使找到一些程序,要么就是把这个工具栏写在具体的画面(图2),要么就是没有源代码的, 我在想,是否别人也 ...

  4. winform设置DataGridView样式 (蓝色)

    本文转载:http://www.cnblogs.com/hailexuexi/archive/2012/04/23/2466398.html 代码: #region DataGridVeiw Styl ...

  5. Java进击C#——应用开发之WinForm环境

    本章简言 上一章笔者讲到关于IO文件操作类,了解如何处理文件流.从这一章开始笔者将讲解相对比较高级的知识点.而本章笔者就对WinForm开发的知识点进行讲解和引导.现在很多业务都是面向于B/S模式的开 ...

  6. 浅析c#中登录窗体和欢迎窗体关闭的问题

    第一次在cnbogs发文章,这次来个很基础的,主要给小白看. 在c#的winform编程中,我们经常会做登录窗体或欢迎窗体,并把他们作为启动窗体. 但是,我们有可能会遇到一些问题. 请看下面的代码: ...

  7. 应用开发之WinForm环境

    本章简言 上一章笔者讲到关于IO文件操作类,了解如何处理文件流.从这一章开始笔者将讲解相对比较高级的知识点.而本章笔者就对WinForm开发的知识点进行讲解和引导.现在很多业务都是面向于B/S模式的开 ...

  8. WinForm数字小键盘/WPF数字小键盘

    模仿原本的WinForm触摸屏小键盘制作WPF触摸屏小键盘 原WinForm触摸屏小键盘样式(WinForm采用Krypton系列控件)如下图: Designer代码如下: // // BtnNum1 ...

  9. WinForm 应用程序禁止多个进程运行

    方法一: 禁止多个进程运行 using System; using System.Collections.Generic; using System.Linq; using System.Window ...

  10. 设置DatagridView的列头样式

    设置DataGridView.ColumnHeaderDefaultCellStyle的BackColor属性会发现没有效果.这是因为在启动了可视样式的时候,BackColor和ForeColor的值 ...

随机推荐

  1. .Net依赖注入、控制反转

    依赖项是指另一个对象所依赖的对象. 使用其他类所依赖的 WriteMessage 方法检查以下 MyDependency 类:   public class MyDependency { public ...

  2. 自己动手从零写桌面操作系统GrapeOS系列教程——6.电脑启动过程介绍

    学习操作系统原理最好的方法是自己写一个简单的操作系统. 按一下电脑上的电源按钮,电脑就启动了,不一会儿电脑屏幕上就出现了登录界面或直接进入了桌面. 这是一个很日常的场景,但有时候会有个疑问:电脑内部是 ...

  3. nginx编译安装以及常用参数详解

    1 基于ansible role实现编译安装nginx 利用ansible控制端10.0.0.8机器,在被控制端10.0.0.18上部署nginx 首先打通ansible控制端与被控制端的基于key验 ...

  4. Visual Studio Code C / C++ 语言环境配置的历程

    前言 从大一开始学习c++用的dev-c++,后来看到老师用的是vs  code,实在是馋它的颜值便去下了vs  2017.至于为什么下载vs 2017呢?是因为下载的时候我以为他们是一样的,便下了v ...

  5. No.2.3

    PC端网页和移动端网页的有什么不同? PC屏幕大,网页固定版心 手机屏幕小,网页宽度多数为100% 如何在电脑里面写代码边调试移动端网页效果? 谷歌模拟器 了解屏幕尺寸概念 屏幕尺寸:指的是屏幕对角线 ...

  6. C:\Windows\System32\drivers\etc\hosts中的文件修改后无法保存

    这个文件定义了IP地址和主机名的映射关系.我们对其进行修改保存时显示没有权限无法保存,我们可以通过以下步骤解决. 1.选中hosts文件,右键点击属性. 2.在属性面板点击安全,选中Users,然后点 ...

  7. 基于线程的并行-Python 并行编程学习笔记(一)

    前言 最近写一些模拟集群智能的算法,虽然机制简单,但是随着个体的增加,设计的计算量就比较大了,尤其是加上matplotlib进行动态展示,使得运算量骤增,看着画面也比较卡.之前想把算法转化成c++代码 ...

  8. 两个jsp界面之间使用window.location.href使用?传递参数以及接受参数

    这篇文章如果能给你带来帮助,不胜荣幸,如果有不对的地方也欢迎批评指正. 网上有很多方法是讲怎么截取字符串啊等等的方法来获取参数,说实话,看着我就觉得费劲,咱们可以换一种思路来思考.一般跳转界面多为前段 ...

  9. MC 末影人

    #include <iostream> #include "minecraft.h" using namespace std; int x=225,y=115,z=23 ...

  10. 安装archlinux系统

    archlinux iso文件下载站点这个iso文件需要保证较新,否则其中的比如libcap的验证密钥过时无法在系统里安装软件包.比如2022年10月7日安装0601版本iso无法通过linux等软件 ...