c#

位置:IT落伍者 >> c# >> 浏览文章

浅析VisualBasic.NET中的资源使用


发布日期:2018年08月02日
 
浅析VisualBasic.NET中的资源使用

在我了解到的程序世界中资源的初次登场是因为程序的国际化当时的可执行文件已不再是单调的英文面孔汉语西班牙语等国际语言的支持强烈要求同样的程序可以使用不同的语言界面在当时将程序逻辑代码和提示信息分离是一个不错的主意堤示信息分离出来成为一个资源文件而独立存在在程序进行编译时再由编译器链接到可执行文件中直到现在资源在这个方面依然扮演着重要的角色以下以的一个小例子说明资源的存在

例一时下许多网上的软件都有什么多国语言版之类的说法实在点就是同一程序在安装或使用过程中有个国家区域选项当你选择了对应的国家时程序就会显示使用相应国家语言的界面其实在编程实现这种功能非常简单只不过是使程序同时嵌入几个不同语言的资源文件而已以下示例就是一个同时支持英文和中文界面的示例程序程序创建完整步骤如下

在中新建一个项目类型选择windows应用程序项目名称改为resourcesample

在form上放一个Lable控件

选择窗体form按以下指示设置属性:

()Locallizable 属性设为True这一步是关键这个属性告诉net环境要使用资源文件来保存窗体及窗体内的各种控件的属性值

()选择窗体的language属性将其设为英语然后按下表设置窗体及lable控件的其它属性:

控件名称属性属性值FormtextFormLabel TextLets speak English!

窗体外观如下

()重新选择窗体的language属性将其设为中文(简体)然后按下表设置窗体及lable控件的其它属性:

控件名称属性属性值Formtext窗体LabelText

让我们说中文!

窗体外观如下

大家也许很奇怪为什么要对窗体及label的text属性进行两次不同的赋值呢?其实答案很简单太聪明了由于我们使用Locallizable 属性告诉net环境要使用资源文件来保存窗体及窗体内的各种控件的属性值当使用不同的language属性它会将窗体及其上控件的属性按语言分别记录在不同的资源文件内不信你将language属性重新设为英语看看第一个英文界面的窗体又跳出来了吧D

如果说可视化编程是光明之途的话那么我们的快乐时光到此结束由于net还没有智能化到会判断什么时候使用什么国家的语言界面的程度(如果net 太智能了程序员就不幸了下岗啊谁受得了?!)所以以下必须由我们自己编写代码确定程序的实际界面显示

打开 form的New过程在InitializeComponent()前加入如下代码(这段代码作用是在窗体初始化组件之前按指定的语言区域信息载入相应的界面资源文件)

Dim tenmDialogResult As DialogResult

tenmDialogResult = MessageBoxShow(请问是使用中文还是英语中文选择OK英文选择CANCEL _

语言选择 _

MessageBoxButtonsOKCancel _

MessageBoxIconQuestion _

MessageBoxDefaultButtonButton _

MessageBoxOptionsDefaultDesktopOnly)

REM 一般情况下程序都是使用读取初始化文件的方法来取得语言设置信息

但本例程为了简便起见仅使用一个对话框提示用户选择适合自己的语言

If tenmDialogResult = DialogResultOK Then 使用中文界面

gstrAppCulture = zhCHS

Else 使用英文界面

gstrAppCulture = en

End If

将需要使用的区域信息放到当前线程的区域信息中

程序窗体会根据设定的信息装载相应的资源文件以显示信息

SystemThreadingThreadCurrentThreadCurrentUICulture = _

New SystemGlobalizationCultureInfo(gstrAppCulture)

剩下的事这没什么好说的了按运行吧在出现对话框时试着点OK或Cancel看看你的杰作吧很酷的同时支持中英文界面的示例程序哦

伟大的思想家会说我们要透过现象看到事物的本质我虽说对哲学不感兴趣但对net在后台到底瞒着我干了些什么见不得光的勾当还是非常好奇的点击解决方案资源管理器点击显示所有文件的按纽很惊奇地发现在formvb下出现了几个后缀名为resx的文件这些家伙就是本文要说明的资源文件了(留意一下资源文件的文件名包含的en和zhCHS的字符这就代表该资源文件储存的语言内容en为英文zhCHS为简体中文)

双击formenresx看一下资源文件是如何储存界面的语言信息的

点击查看大图

左边的数据源显示资源文件的实际数据(data)以及资源文件的文件版本信息(resheader)我只关心资源文件的实际数据储存右边的表列出了储存的数据:很显然name代表控件的属性(其实是引用资源数据的键)后面的value代表对应键的实际数据(在程序中界面显示的值就靠这里了你可以试着把Lets apeak English改一下然后运行一下程序看看)comment代表注释type代表数据的类型mimetype就是资源数据的MIME 类型(当你窗体或picturebox存有图片时你会看到这里有一个很长的值由于这个对编程作用不大不作解释)我们还可以在这个界面中插入新的资源数据只要填写好name和value就可以了

明白了资源文件后我们再看一下代码中是怎样引用这引些值的打开窗体的代码编辑器展开Windows 窗体设计器生成的代码这一代码段找到窗体的Private Sub InitializeComponent()过程

第一句为:

Dim resources As SystemResourcesResourceManager = New SystemResourcesResourceManager(GetType(Form))

这句代码的含义就是产生一个resourcemanager对象来对form的资源文件进行控制由于net 会根据线程的区域属性调用窗体的不同语言的资源文件所以我们前面示例中将改变线程区域信息的代码放在InitializeComponent()过程之前以便net在创建resources对象时调用正确的语言资源文件

接下来就是一大堆对控件属性进行赋值的语句了看一下label的text 属性是如何赋值的就会明白资源数据的使用方法了

MeLabelText = resourcesGetString(LabelText)

很简单使用ResourceManager的方法就可以获得实际需要的资源数据了必要时可以可以使用getobjcet方法取得数据然后再用Ctype将其转为指定的类型

写到这儿本来按原计划我是想收笔的但是天气依然阴沉沉很闷干脆就将资源使用的终极杀招也介绍一下好了资源发展到现在已不权是简单地解决程序国际化的界面方面了在net中可以使用资源将任意文件嵌入到你的可执行文件中在需要时再用流的方式读出使用(是任意文件哦而且方法非常简单)好象很酷的样子吧以下我就用另一个示例说明一下

示例在net中可执行文件中嵌入一个文本文件

以前我做程序版权使用协议信息总是放在一个txt文本文件中打包时和可执行文件放在一起在安装时释放到程序的安装路径然后再打开使用这种做法有两大坏处一是这个文件很容易被其它人修改二是可以套用蜡笔小新的一句话这种做法太不成熟了吧!现在我使用一个新的方法就是将协议和可执行文件结合在一起在程序运行时读出使用当然这就全靠资源的作用了步骤如下

在中新建一个项目类型选择windows应用程序项目名称改为resourcesample

点击项目菜单选择添加现有项接着会弹出一个文件对话框将文件类型改为所有文件后选择要嵌入的txt文件(其实这时你可选择任意文件只要你喜欢*接着你会在解决方案资源管理器中发现你新加入的文件名如图

关键的一步到了在解决方案资源管理器中点击你刚加入的文件名然后在属性窗体中将 加成操作 这一属性改为嵌入的资源这将告诉net刚加入的文件将会作为资源链接进可执行文件中留意一下文件名哦这在后面的程序中也很重要强烈建议使用小写文件名!如下图

接下就是在程序中用代码读出这个文件的内容

在Form_Click事件中加入代码如下所示

Private Sub Form_Click(ByVal sender As Object ByVal e As SystemEventArgs) Handles MyBaseClick

Dim tobjStream As IOStream = MeGetTypeAssemblyGetManifestResourceStream(resourcesampleLicensetxt)

Dim tobjStreamReader As New IOStreamReader(tobjStream SystemTextEncodingDefault)

Dim tstrLicense As String = tobjStreamReaderReadToEnd

如果是图象就可以使用dim tobjBMP as new bmp(tobjstrem)的方法直接得到资源内容

MessageBoxShow(tstrLicense)显示刚才读得的结果

End Sub

在此对上述代码进行一点解释net是通过Assembly的GetManifestResourceStream读出嵌入在可执行文件的资源并以IOStream对象返回(反正得到了这个流就好象你时进行文件流操作读/写到磁盘或象我一样在程序内部处理都由你自己决定了)这个方法的唯一参数是资源的唯一标识是按如下方式组成的程序集的根命名空间++资源在属性窗口显示的文件名(这是区分大小写的在上文已提醒你注意了哦而且这个标识法在C#中是不同的别问我为什么谁叫你不和我一样使用

程序集的根命空间的名你可以从项目菜单下的XXXX(XXXX是你的项目名称可不要认为是骂人的话)属性中看到

点击查看大图

其余的代码就是以流方式读文件了很简单吧

按生成菜单下的生成解决方案然后到你可执文件的目录下看看你会发现除了可执行文件外没有别的文本文件因为文本文件已以资源的方式存在于可执行文件中啦运行一下看看效果啊(一些想做黑客的菜鸟又有什么怪怪的想法藏木马?……)

资源的使用就介绍到此为至吧窗外依然小雨菲菲在虚幻的网络和残酷的现实边缘排徊久了写文章都有点怪怪的请大伙儿原谅祝大伙编程愉快

上一篇:纯C#钩子实现及应用

下一篇:如何将C#时间格式转换为中文格式