在以前我做程序的时候,一般在登录窗口里面显示程序名称,登录窗口一般设置一张背景图片,由于程序的名称一般都是确定的,所以也不存在太大的问题,不过如果客户定制不同的系统的时候,需要使用Photoshop修改下图层的文字,在生成图片,然后替换一下也可以了。不过本着减少客户使用繁琐性,也可以使用空白名称的通用图片,配上使用GDI+的方式动态绘制系统名称的方式处理,发现效果也还不错,本篇随笔介绍一下这个处理的过程。

1、使用图片编辑程序修改的方式

如果我们采用传统的图片编辑方式,一般我们倾向于使用Photoshop来处理,不过现在也可以使用剪影来实现更多的效果了。

如原先是采用Photoshop来编辑登录图片的内容,这样系统登录的时候,就可以直接采用背景图片了。

需要的时候,在Photoshop找到图片源文件,替换一下内容,重新生成图片即可。

然后再系统的登录界面中,替换一下使用Photoshop生成的背景图片,就可以简单的实现了效果的替换了。

使用这种方式创建的文字效果比较丰富,可以充分利用图片编辑软件创建的字体效果,不过就是需要安装这个巨无霸软件。

2、使用软件GDI+的方式动态绘制系统名称

前面使用Photoshop生成的背景图片,是一种解决方案,如果我们有相关的背景图片,也可以使用软件的GDI+的方式动态绘制系统名称。

首先我们使用Photoshop等图片编辑软件,编辑一下图片,保留标题位置为空白,然后也是通用的设置登录界面的背景,至于文字,我们通过登录窗口的Paint事件,使用GDI+的方式绘制系统名称。

我们的软件系统名称,一般是设置在配置文件中的,如下是WInform的App.config文件内容。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<!--指定默认的数据库类型,如果不指定则使用第一个连接字符串-->
<add key="DefaultDb" value="sqlserver" /> <!--软件名称-->
<add key="ApplicationName" value="SqlSugar开发框架" />
<!--开发商名称-->
<add key="Manufacturer" value="广州爱奇迪软件科技有限公司" />

如下是系统的绘制逻辑处理,由于处理代码行数较多,就抽取为辅助函数,方便查看重用。

/// <summary>
/// 系统登录界面
/// </summary>
public partial class Login : DevExpress.XtraEditors.XtraForm
{
/// <summary>
/// 配置文件对象
/// </summary>
private AppConfig config = new AppConfig(); /// <summary>
/// 窗体构造函数
/// </summary>
public Login()
{
InitializeComponent(); //动态绘制软件的系统名称
this.Paint += (s, e)=>
{
string applicationName = config.AppConfigGet("ApplicationName") ?? "SqlSugar开发框架";
applicationName = JsonLanguage.Default.GetString(applicationName);
MyHelper.Draw3DTitle(e.Graphics, applicationName, Color.Black, Color.Gray);
};
}

上面的MyHelper.Draw3DTitle就是我们封装的处理方式,用于对GDI+的处理过程进行剥离,提高代码的可阅读性。

在介绍代码的详细实现过程前,我们来看看使用GDI+实现的效果,其中字体使用了一些3D的效果。

上面登录界面的效果是自动根据内容生成,其中文字如果比较多,也会自动根据宽度进行适应,把字体大小调整合适。

由于实现的效果相对不是很复杂,因此代码我就全部贴出来供参考了。主要就是对字体进行调整,以及增加3D效果的处理。

        public static void Draw3DTitle(Graphics g, string title, Color frontColor, Color shadowColor, bool useGradient = false,
int depth = 5,
string fontName = "华文中宋", FontStyle fontStyle = FontStyle.Bold, int maxFontSize = 36,
int startX = 140, int startY = 100, int targetWidth = 450, int targetHeight = 100)
{
// 获取适合目标宽度的字体大小
var font = GetAdjustedFont(g, title, fontName, fontStyle, targetWidth, maxFontSize, 6); // 绘制阴影
for (int i = depth; i >= 0; i--)
{
using (Brush shadowBrush = new SolidBrush(Color.FromArgb(255 - (depth - i) * 25, shadowColor)))
{
g.DrawString(title, font, shadowBrush, new PointF(startX + i, startY + i));
}
} Brush textBrush = new SolidBrush(frontColor);
// 创建渐变填充
if (useGradient)
{
textBrush = new LinearGradientBrush(new Rectangle(startX, startY, targetWidth, targetHeight), frontColor, Color.Blue, 45f);
}
// 绘制前景文本
g.DrawString(title, font, textBrush, new PointF(startX, startY));
} /// <summary>
/// 根据目标宽度,调整字体大小
/// </summary>
private static Font GetAdjustedFont(Graphics g, string text, string fontName, FontStyle fontStyle, int targetWidth, int maxFontSize, int minFontSize)
{
// 调整字体大小,直到文本适合目标宽度
for (int size = maxFontSize; size >= minFontSize; size--)
{
var testFont = new Font(fontName, size, fontStyle);
var textSize = g.MeasureString(text, testFont);
if (textSize.Width <= targetWidth)
{
return testFont;
}
}
// 如果没有合适的大小,返回最小字体大小
return new Font(fontName, minFontSize, fontStyle);
}

以上就是我们SQLSugar开发框架中,对于动态程序标题的另外一种解决方案。

在Winform程序中动态绘制系统名称,代替图片硬编码名称的更多相关文章

  1. dotnetnuke 中使用ado.net entityframework 如果在程序中动态调用系统的连接字符串信息

    1,打开如下图的Model1.Context.cs文件 2,找到 Base:(ConnString.conn)是我改的.默认生成的是"name=实体连接字符串" Connstrin ...

  2. C#中Winform程序中如何实现多维表头【不通过第三方报表程序】

    问题:C#中Winform程序中如何实现多维表头. 在网上搜了很多方法,大多数方法对于我这种新手,看的都不是很懂.最后在新浪博客看到了一篇比较易懂的文章:[DataGridView二维表头与合并单元格 ...

  3. 在Winform程序中设置管理员权限及为用户组添加写入权限

    在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身 ...

  4. (转)在Winform程序中设置管理员权限及为用户组添加写入权限

    本文转载自:http://www.cnblogs.com/wuhuacong/p/5645172.html 在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行 ...

  5. Android 在程序中动态添加 View 布局或控件

    有时我们需要在程序中动态添加布局或控件等,下面用程序来展示一下相应的方法: 1.addView 添加View到布局容器 2.removeView 在布局容器中删掉已有的View 3.LayoutPar ...

  6. WinForm程序中两份mdf文件问题的解决

    在项目中用程序中嵌入mdf文件的方式来进行SQLServer数据库开发非常方便,用来发布开源项目等很方便,点击就可以运行,免部署,特别是在教学中用起来更加方便,老师不用先将数据库文件detach再发给 ...

  7. 在MVC应用程序中动态加载PartialView

    原文:在MVC应用程序中动态加载PartialView 有时候,我们不太想把PartialView直接Render在Html上,而是使用jQuery来动态加载,或是某一个事件来加载.为了演示与做好这个 ...

  8. 在C#中winform程序中应用nlog日志工具

    在C#中winform程序中应用nlog日志工具,配置文件简单应用. 文件名 nlog.config,请注意修改属性为"始终复制",发布时候容易遇到不存在文件的错误提示. 通过Nu ...

  9. 解决Winform程序在不同分辨率系统下界面混乱

    问题分析:          产生界面混乱的主要原因是,winform程序的坐标是基于点(Point)的,而Point又与DPI相关,具体就是 一英寸 =72Points 一英寸 =  96pixel ...

  10. Halcon的HWindowControl控件在WinForm程序中的使用介绍(重点解决图片缩放的问题)

     Halcon的HWindowControl控件在WinForm程序中的使用介绍(重点解决图片缩放的问题) 2016-12-04 20:11 362人阅读 评论(4) 收藏 举报  分类: Halco ...

随机推荐

  1. [FAQ] eggjs/egg 自定义 favicon.ico

      从  egg 项目配置里找到这一段代码: https://github.com/eggjs/egg/blob/master/config/config.default.js#L205C21-L20 ...

  2. [GPT] 神经网络模型方面的课程、神经网络模型与深度学习

      现在有很多关于神经网络模型的课程.以下是一些比较受欢迎的神经网络模型课程: Stanford CS231n:卷积神经网络(CNNs)课程 Deep Learning Specialization: ...

  3. [FE] Quasar 性能优化: 减小 vendor.js 尺寸

    默认情况下,出于性能和缓存的原因,Quasar 所有来自 node_modules 的东西都会被注入到 vendor 中. 但是,如果希望从这个 vendor.js 中添加或删除某些内容,可以如下这样 ...

  4. [FAQ] Vue 如何控制标签元素的某个属性的显示 ?

    这需要借助 v-model 的用法,动态决定元素的展示. <q-btn :disable="2 > 1">按钮</q-btn> 展示结果是:<q ...

  5. Fiddler对安卓模拟器中的app抓包

    工具资源 Fiddler: https://www.telerik.com/download/fiddler Xposed Installer: https://repo.xposed.info/mo ...

  6. linux环境下java调用C/C++动态库(JNI技术:参数为指针与结构体)

    一.JNI技术 JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植. SUN公司发布的Java 本地接口(JNI)提供了将 ...

  7. C 语言编程 — 高级数据类型 — 指针

    目录 文章目录 目录 前文列表 指针 声明指针 使用指针 NULL 指针 指针的算术运算 指向指针的指针 将指针作为实际参数传入函数 从函数返回指针 一个古老的笑话 前文列表 <程序编译流程与 ...

  8. 4G LTE/EPC UE 的附着与去附着

    目录 文章目录 目录 UE 附着 UE 与 MME 建立 NAS 连接 UE 附着协议全景 UE 附着流程 UE 去附着 UE 侧发起的去附着 MME 发起的去附着 HSS 发起的去附着 UE 附着 ...

  9. IceRPC之传入响应和拦截器

    作者引言 .Net 8.0 下的新RPC 很高兴啊,我们来到了IceRPC之传入响应和拦截器->快乐的RPC, 基础引导,让自已不在迷茫,快乐的畅游世界. 传入响应 Incoming respo ...

  10. 《最新出炉》系列入门篇-Python+Playwright自动化测试-47-自动滚动到元素出现的位置

    1.简介 在我们日常工作中或者生活中,经常会遇到我们的页面内容较多,一个屏幕范围无法完整展示内容,我们就需要滚动滚动条去到我们想要的地方,如下图页面,我们虽然在豆瓣首页,但是内容并不完整,如果我们想要 ...