每一个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. JZOJ 3992.Christmas

    题目大意 给定一个数列,支持区间加一个数和区间取 \(max\),询问单点询问数值和它被更改的次数 思路 模板的吉司机线段树 维护区间最小值和严格次小值以及最小值的个数 针对询问维护区间和以及区间修改 ...

  2. vue element-ui table 实现自动滚动效果

    <el-table :data="tableData" stripe class="swiper-page-table" ref="table& ...

  3. Python连接hadoop-hive连接方法

    import impala.dbapi as ipdbconn = ipdb.connect(host='IP', port= 端口, database='数据库名', auth_mechanism= ...

  4. PostgreSQL 并行计算算法,参数,强制并行度设置

    一.优化器并行计算的并行度计算方法 1.总worker进程数 postgres=# show ; max_worker_processes ---------------------- 128 (1 ...

  5. SpringBoot 面试问答总结(VIP典藏版),最详细!全面!爆肝!

    最详细的SpringBoot面试问题干货,点赞收藏慢慢看 1.SpringBoot 面试问答总结 Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主 ...

  6. day09-MyBatis缓存

    MyBatis缓存 mybatis – MyBatis 3 | cache MyBatis 一级缓存全详解(一) MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制. 为了 ...

  7. Linux操作命令(五)1.find命令 2.xargs命令

    1.find命令(一) 查找,沿着文件层次结构向下遍历,匹配符合条件的文件,并执行相应的操作 参数 描述 -print find 命令将匹配的文件输出到标准输出 -exec find 命令对匹配的文件 ...

  8. sqlite没法查出数据

    能够正常插入数据,再次运行插入数据的代码,报错主键重复,说明数据库数据是存在的. 只是插入后再查出就没有数据,显示得是undefined. 检查一下语法,没问题啊,到底啥问题(图中的红色波浪线是ts的 ...

  9. 01-搭建小巧完善的Kubernetes环境

    安装Docker Docker安装和基础命令 安装Minikube minkkube start 安装minikube curl -LO https://storage.googleapis.com/ ...

  10. Column count doesn't match value count at row 1存储的数据与数据库表的字段类型定义不相匹配

    一.造成这个原因可能是一个关于创建json数据类型的mysql表格插入的一个报错提示: 26行为错误示范:27是正确书写规范.