荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Jobs (温少), 信区: Visual
标  题: 访问注册表--通过VJ6来处理Windows注册表
发信站: BBS 荔园晨风站 (Sat Feb 19 17:52:34 2000), 转信



访问注册表--通过VJ6来处理Windows注册表

Microsoft Visual J++ 6.0(VJ6)向Java开发人员提供了Windows AP访问注册表
--通过VJ6来处理Windows注册表

Microsoft Visual J++ 6.0(VJ6)向Java开发人员提供了Windows API的调用,
其中包含了Windows结构中的重要组件,比如系统的注册表。

我们都知道Java的目的是为了实现跨平台的应用程序开发,因此我们不必惊讶
Java语言不支持系统的注册表和其它Windows相关的特性。有一些Java开发者强烈
反对VJ6引入的新的Java 语言的扩展,而其它的人则不关心跨平台的开发,他们
想编写Windows相关的应用程序,使用一种现代的、功能强大的、面向对象的语言
--Java。

系统注册表是Windows 95、Windows 98和Windows NT结构的一个重要部分,注册
表的真正强大功能--从一个应用程序开发者的角度来说--就是能够存储您的应用
程序相关的信息。如果您想要使您的应用程序对用户友好,一个方法是在应用程
序退出时把设置保存起来。这样,一些象窗口位置、缺省数据库和最近访问的文
件等设置将在下次用户载入应用程序时成为缺省设置。

本文将简要地讨论系统注册表的基础,还将介绍允许您方便地访问系统注册表的
VJ6扩展。举例的应用程序使用VJ6用户界面的另一个新特性--Windows基本类库(
WFC)。

注册表
有经验的开发人员都知道系统注册表,如果你犯了一个错误删除或者修改了错误
的选项,你可能不得不重新安装Windows。如果你在修改注册表之前知道你想要做
什么,你就可以安全地使用注册表了。最安全的方法是在你改变任何注册表选项
之前先备份系统注册表,这样如果你不小心犯了一个错误修改或者删除了错误的
选项的话也不会出现灾难性的后果。

[object manager]
options = 1,1,1,1,1,1,1,2,1,0,1
connect on startup = 0

[Reports]
ReportDefFileName = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\reports.erp
ReportFontSize = -11

[Recent Template List]
Template1 = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\TEMPLATE\Dimens.ert
Template2 = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\TEMPLATE\Sample.ert
Template3 = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\TEMPLATE\Progress.ert

图一:一个.INI文件示例

一些开发人员完全避免使用注册表,他们把配置信息保存在.INI文件中。如果你
曾经在Windows 3.1或者更早的版本中开发应用程序,你会记得配置信息是保存在
文本文件中,通常在\Windows子目录中,带有一个.INI的文件扩展名。一些开发
人员争论说,如果仍然可以使用.INI文件,为什么要转而使用注册表呢?

使用注册表的原因有很多,注册表比.INI文件更加灵活。.INI文件是更加原始的
文本文件,你存储于其中的任何值都必须转换成一个文本字符串。而注册表就不
一样了,因为它是一个二进制的数据库,你不需要转换就可以直接在其中存储许
多数据类型。注册表的最大优势是它只有一个,也就是说它把所有Windows应用程
序在从一个会话切换到另一个会话时必须保持一致的所有数据存放在一个集中的
地点。这和.INI类型文件的系统有着显著的不同,在.INI文件类型的系统中,所
有的.INI文件散布在目录树中。

如果你的应用程序不在一个.INI文件中存储配置信息,你仍然需要对注册表以及
如何读取其中的信息非常熟悉,因为几乎所有Windows 95、Windows 98和Windows
NT的商业软件和硬件都和操作系统一样在注册表中存储信息。通过学习注册表中
的选项,你可以学到许多关于Windows结构以及不同应用程序如何工作的知识。此
外,注册表还帮助应用程序之间的协同,如果你忽略了注册表,其它的应用程序
将不能访问你的软件。


在注册表中存储信息的另一个优势就是你的程序可以在每一个用户的基础上存储
信息。用户可以配置他们自己的应用程序设置,Windows注册表自动地为每一个用
户存储和获取设置信息。你不需要强迫每一个用户使用同样的设置,或者为管理
不同的用户设置而设计复杂的计划。 Windows注册表为你处理了所有的细节信息


VJ6使得访问注册表变得相对简单,那些从Visual Basic(VB)转向VJ++的应用程
序开发人员将发现运用注册表的强大功能将变得十分容易。VB能够让你获得注册
表中的基本特性并访问注册表中绝大多数的信息,但是如果你的要求十分复杂的
话,你仍然需要使用Windows API。VB通过限制可以利用的特性把开发人员从复杂
性中解放出来。而VJ++着让你处于一种比较危险的处境中。

注册表--就和老的.INI文件相同--用名字-数值对的方式存储信息。例如,在图一
中的示例.INI文件中列出了基本的变量,每一个紧接着一个等于号,然后是一个
数值,下面是典型的一行:

connect on Startup=0

每一节的头字节(比如object manager)被中括号括起来。

注册表在信息管理方面则更加灵活,它允许你在一个字段中嵌套一个字段。根键
位于最高级别。

Regedit是一个你可以用来直接编辑注册表的小工具(Regedit.exe在\Windows或
者\Winnt目录中)。在根键的下面有许多层的子键。这个结构就象一个文件系统
,根键就象一个根目录,子键就象子目录,你就象嵌套子目录一样嵌套子键。


你可以用Regedit来检查系统注册表中的信息,只要你不修改或者删除任何数值或
者子键,你就不会存在任何损害操作系统或者你的软件/硬件的配置的危险。实际
上,查看注册表可以学到很多东西。

SOFTWARE是HKEY_LOCAL_MACHINE键中一个子键,如果你检查你的计算机中的注册
表信息,你会发现其它的软件商已经需要调
用API。VJ6本身包括了访问注册表的类,你可以通过这些类进行所有的注册表访
问。除非你的要求特别复杂。

这些类位于com.ms.wfc.app库中。Registry类可以很方便地得到注册表的根键,
在这里根键是一个RegistryKey对象。一个RegistryKey对象代表注册表中的一个
键或者子键,你可以使用RegKey类或者RegistryKey类,RegKey类提供的选择较少
,你只能访问四个根键:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER

HKEY_LOCAL_MACHINE以及HKEY_USERS。当使用RegKey类时,数据的类型被限制在
字符串、整型和字节类型。我们在本文中将使用RegistryKey类以及相关的
Registry类。

RegistryKey类被定义为final类型,因此你无法通过new这个操作符来声明一个实
例,你也不能继承它。为了得到RegistryKey的一个实例,你可以使用静态的
getBassClass,也可以使用 Registry类的成员函数。下面的代码对两种方法各举
一例。我喜欢使用Registry类中的一个成员函数,因为当我想对注册表立即进行
操作时可以节省一行代码。下面的例程首先获得RegistryKey类的一个实例,然后
对注册表立即进行一个操作。在这里是打开一个子键,如果这个子键不存在的话
,将创建一个子键。

//Creating an instance of RegistryKey class wi个方法有一个布尔值的选项可以让你设
置成只读的模式
。唯一的技巧就是对getValue返回的值进行类型转换。记住注册表是一个二进制
文件,你可以直接存储多种数据类型。getValue将返回一个对象并需要一个显式
的类型转换。在下面的代码中,数据值被转换成字符串的类型:


objRegistryKey = Registry.CURRENT_USER.getSubKey(
        "Software\\RegistryTest\\Configuration", true);
if (objRegistryKey = = null)
        alertNoSubKey("HKEY_CURRENT_USER\\Software" +
            "\\RegistryTest\\Configuration");
else
{
        strSetting ENT_USER\\Software" +
                        "\\RegistryTest\\Configuration");
else
{
        strSetting = (String)objRegistryKey.setValue(
                    "TestValue", "Some value");
    objRegistryKey.close();
}

删除一个子键更加简单。一样,确认把getSubKey布尔值这个参数设置成false或
者干脆不带这个参数:

objREgistryKey = Registry.CURRENT_USER.getSubKey(
        "Software\\RegistryTest\Configuration", false);
if (objRegistryKey = = null)
        alertNoSubKey ("HKEY_CURRENT_USER\\Software" +
                        "\\RegistryTest\\Configuration");
else
{
        strSetting =
            (String)objRegistryKey.DeleteValue ("TestValue");
        objRegistryKey.close ();
}

创建一个测试程序
本文章中的范例工程文件使用WFC生成一个对话框,用来测试对四个不头缦招裕〔灰境
蛘咝薷某瞬馐猿绦蛉笔∩柚弥?
外的注册表项。

有三种操作注册表的私有方式:getSetting、saveSetting和deleteSetting。另
外还有两种私有方式提供额外支持:composeSubKey,它能够把编辑框中的文字组
合成为一个子键字符串;另一个是alertNoSubKey,当用户试图读取或者删除一个
不存在的子键时,它将产生一个对话框。

因为测试程序初始化了一个和Registry对象相关的RegistryKey对象,它在获取、
保存和删除设置时使用了一个switch语句,switch语句对选择特定根键所对应的
RegistryKey对象进行初始化。


无限的可能性
当今的用户希望软件易于定制,容易进行控制。注册表的设置允许你的应用程序
记住用户的个性设置。同时它还为应用程序的性能数据提供了一个存储的地点,
因此你的应用程序可以根据用户的需求进行自我优化。

比如,你可以在注册表中保存最近使用过的文件。Word和电子数据表能够这样,
你的应用程序也可以这样。你可以使用getValueCount来确定在你的最近使用列表
(MRU)中存在多少文件。这个计数器可以控制一个for的循环。有些应用程序设
计很巧妙,它们在MRU中使用文件名作为数据值,这就好象把它们放在变量赋值的
左边,而它们在数据值中输入了一个空白字符串。re.*;
import com.ms.wfc.ui.*;

/*
*This class can take a variable number of parameters on the command line.
Program
*execution begins with the main() method. The class constructor is not invoked
unless
*an object of type "Form1" created in the main() method
*/
public class frmRegistryTest extends Form
{
        //Root registry key the user chooses.
        RegistryKey objRootKey;
        //Name of root key, for error messages.

        Public frmRegistryTest()
        {
            //Required for Visual J++ Forms Designer support.
            initForm();

            //Initialize form values to use the HKEY_CURRENT_USER
            //registry key and the Software subkey.
            RbRoot2.setChecked(true);
            txtSubKey.setText("Software");
             }

        private void btnDeleteSetting_click(Object sender, Event e)
        {
            deleteSetting();
        }

        private void alertNoSubKey(String strSubKey)
        {
            int intAction = MessageBox.show("Registry SubKey: '" +
                strSubKey + "' Not Found.", "No Registry Entry.");
            return;
        }

        private String composeSubKey()
        {

            //Takes text from edit boxes on the form.
            //Creates a registry SubKey string.
            String strSubKey;
            String strTemp;

            StrSubKey = txtSubKey.getText();

            //If the application name is not an empty string,
            //add it to the subkey.
            StrTemp = txtApplication.getText();
 the registry to the appropriate SubKey.
            //Opens the SubKey in read-only mode for safety.
            RegistryKey objRegistryKey =
                ObjRootKey.getSubKey(composeSubKey(), true);
            if(objRegistryKey = = null)
                alertNoSubKey(strRootKey + composeSubKey());
            else
            {
                strSetting = objRegistryKey.getValue(
                    txtName.getText(), "").toString();
                objRegistryKey.close();
                return strSetting;
            }

            return "";
        }

        private void saveSetting()
        {
            //Set the registry to the appropriate SubKey.
            //Creates the SubKey,if it doesn't already exist.
            RegistryKeyKey.close();
                txtName.setText("");
                txtValue.setText("");
            }
        }

        private void rbRoot1_checkedChanged(Object source, Event e)
        {
            if (rbRoot1.getChecked())
            {
                objRootKey = Registry.CLASSES_ROOT;
                strRootKey = "HKEY_CLASSES_ROOT\\";
            }
        }

    private void rbRoot2_checkedChanged(Object source, Event e)
        {
            if (rbRoot2.getChecked())
            {
                objRootKey = Registry.CURRENT_USER;
                strRootKey = "HKEY_CURRENT_USER\\";
            }
        }

    private void rbRoot3_checkedChanged(Object source, Event e)
        {
            if (rbRoot3.getChecked())
            {
              iner();
GroupBox grpRoot = new GroupBox();
protected RadioButton rbRoot1 = new RadioButton();
protected RadioButton rbRoot2 = new RadioButton();
protected RadioButton rbRoot3 = new RadioButton();
protected RadioButton rbRoot4 = new RadioButton();
protected Button btnGetSetting = new Button();
protected Button btnSavesetting = new Button();
protected Button btnDeletesetting = new Button();
Label lblSubKey = new Label();
protected Edit txtSubKey = new Edit();
Label lblApplication = new Label();
Label lblSection = new Label();
Label lblName = new Label();
Label lblValue = new Label();
protected Edit txtApplication = new Edit();
protected Edit txtSection = new Edit();
protected Edit txtName = new Edit();
protected Edit txtValue = new Edit();

private void initForm()
{
        this.setText("Registry Test");
        this.setAutoScaleBaseSize(13);
        this.setClientSize(new Point(500, 190));

        grpRoot.setLocation(new Point(5, 1));
        grpRoot.setSize(new Point(160, 102));
        grpRoot.setTat3.setTabIndex(2);
        rbRoot3.setText("HKEY_LOCAL_MACHINE");
        rbRoot3.addOnCheckedChanged(new
EventHandler(this.rbRoot3_checkedChanged());

        rbRoot4.setLocation(new Point(10, 80));
        rbRoot4.setSize(new Point 148, 12));
        rbRoot4.setTabIndex(3);
        rbRoot4.setText("HKEY_USERS");
        rbRoot4.addOnCheckedChanged(new
EventHandler(this.rbRoot4_checkedChanged());

        btnGetSetting.setLocation(new Point(176, 8));
        btnGetSetting.setSize(new Point(74, 25));
       Point(176, 72));
        btnGetSetting.setSize(new Point(74, 25));
        btnGetSetting.setTabIndex(12);
        btnGetSetting.setText("Delete Setting");
        btnGetSetting.addOnClick(new EventHandler(this.btnGetSetting_click));

        lblSubKey.setLocation(new Point(7, 108));
        lblSubKey.setSize(new Point(80, 12));
        lblSubKey.setTabIndex(1);
        lblSubKey.setTabStop(false);
        lblSubKey.setText("");

        txtSubKey.setLocation(new Point(7, 124));
        txtSubKey.setSize(new Point(490, 20);
        txtSubKey.setTabIndex(4);
        txtSubKey.setText("");

        lblApplication.setLocation(new Point(7, 144));
        lblApplication.setSize(new Point(80, 12));
        lblApplication.setTabIndex(2);
        lblApplication.setTtion.setSize(new Point(80, 12));
        txtApplication.setTabIndex(5);
        txtApplication.setText("");

        txtSection.setLocation(new Point(114, 157));
        txtSection.setSize(new Point(100, 20));
        txtSection.setTabIndex(6);
        txtSection.setText("");

        txtName.setLocation(new Point(222, 157));
        txtName.setSize(new Point(100, 20));
        txtName.setTabIndex(7);
        txtName.setText("");

txtValue.setLocation(new Point(329, 157));
txtValue.setSize(new Point(100, 20));
txtValue.setTabIndex(8);
txtValue.setText("");

this.setNewControls(new Control[]{
        txtSubKey;
        lblSubKey;
        txtValue;
        txtName;
        txtSection;
        txtApplication;
        lblValue;
        lblName;
        lblSection;
        lblApplication;
        btnDeleteSetting;
        btnSaveSetting;
        btnGetSetting;
        grpRoot});
grpRoot.setNewControls(new Control[]{
        rbRoot4,
        rbRoot3,
        rbRoot2,
        rbRoot1});
}
//NOTE: End of Form车淖⒉岜怼?

我们都知道Java的目的是为了实现跨平台的应用程序开发,因此我们不必惊讶
Java语言不支持系统的注册表和其它Windows相关的特性。有一些Java开发者强烈
反对VJ6引入的新的Java 语言的扩展,而其它的人则不关心跨平台的开发,他们
想编写Windows相关的应用程序,使用一种现代的、功能强大的、面向对象的语言
--Java。

系统注册表是Windows 95、Windows 98和Windows NT结构的一个重要部分,注册
表的真正强大功能--从一个应用程序开发者的角度来说--就是能够存储您的应用
程序相关的信息。如果您想要使您的应用程序对用户友好,一个方法是在应用程
序退出时把设置保存起来。这样,一些象窗口位置、缺省数据库和最近访问的文
件等设置将在下次用户载入应用程序时成为缺省设置。

本文将简要地讨论系统注册表的基础,还将介绍允许您方便地访问系统注册表的
VJ6扩展。举例的应用程序使用VJ6用户界面的另一个新特性--Windows基本类库(
WFC)。

注册表
有经验的开发人员都知道系统注册表,如果你犯了一个错误删除或者修改了错误
的选项,你可能不得不重新安装Windows。如果你在修改注册表之前知道你想要做
什么,你就可以安全地使用注册表了。最安全的方法是在你改变任何注册表选项
之前先备份系统注册表,这样如果你不小心犯了一个错误修改或者删除了错误的
选项的话也不会出现灾难性的后果。

[object manager]
options = 1,1,1,1,1,1,1,2,1,0,1
connect on startup = 0

[Reports]
ReportDefFileName = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\reports.erp
ReportFontSize = -11

[Recent Template List]
Template1 = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\TEMPLATE\Dimens.ert
Template2 = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\TEMPLATE\Sample.ert
Template3 = C:\PROGRA-1\LOGICW-1\ERWIN3-1.5\TEMPLATE\Progress.ert

图一:一个.INI文件示例

一些开发人员完全避免使用注册表,他们把配置信息保存在.INI文件中。如果你
曾经在Windows 3.1或者更早的版本中开发应用程序,你会记得配置信息是保存在
文本文件中,通常在\Windows子目录中,带有一个.INI的文件扩展名。一些开发
人员争论说,如果仍然可以使用.INI文件,为什么要转而使用注册表呢?

使用注册表的原因有很多,注册表比.INI文件更加灵活。.INI文件是更加原始的
文本文件,你存储于其中的任何值都必须转换成一个文本字符串。而注册表就不
一样了,因为它是一个二进制的数据库,你不需要转换就可以直接在其中存储许
多数据类型。注册表的最大优势是它只有一个,也就是说它把所有Windows应用程
序在从一个会话切换到另一个会话时必须保持一致的所有数据存放在一个集中的
地点。这和.INI类型文件的系统有着显著的不同,在.INI文件类型的系统中,所
有的.INI文件散布在目录树中。

如果你的应用程序不在一个.INI文件中存储配置信息,你仍然需要对注册表以及
如何读取其中的信息非常熟悉,因为几乎所有Windows 95、Windows 98和Windows
NT的商业软件和硬件都和操作系统一样在注册表中存储信息。通过学习注册表中
的选项,你可以学到许多关于Windows结构以及不同应用程序如何工作的知识。此
外,注册表还帮助应用程序之间的协同,如果你忽略了注册表,其它的应用程序
将不能访问你的软件。


在注册表中存储信息的另一个优势就是你的程序可以在每一个用户的基础上存储
信息。用户可以配置他们自己的应用程序设置,Windows注册表自动地为每一个用
户存储和获取设置信息。你不需要强迫每一个用户使用同样的设置,或者为管理
不同的用户设置而设计复杂的计划。 Windows注册表为你处理了所有的细节信息


VJ6使得访问注册表变得相对简单,那些从Visual Basic(VB)转向VJ++的应用程
序开发人员将发现运用注册表的强大功能将变得十分容易。VB能够让你获得注册
表中的基本特性并访问注册表中绝大多数的信息,但是如果你的要求十分复杂的
话,你仍然需要使用Windows API。VB通过限制可以利用的特性把开发人员从复杂
性中解放出来。而VJ++着让你处于一种比较危险的处境中。

注册表--就和老的.INI文件相同--用名字-数值对的方式存储信息。例如,在图一
中的示例.INI文件中列出了基本的变量,每一个紧接着一个等于号,然后是一个
数值,下面是典型的一行:

connect on Startup=0

每一节的头字节(比如object manager)被中括号括起来。

注册表在信息管理方面则更加灵活,它允许你在一个字段中嵌套一个字段。根键
位于最高级别。

Regedit是一个你可以用来直接编辑注册表的小工具(Regedit.exe在\Windows或
者\Winnt目录中)。在根键的下面有许多层的子键。这个结构就象一个文件系统
,根键就象一个根目录,子键就象子目录,你就象嵌套子目录一样嵌套子键。


你可以用Regedit来检查系统注册表中的信息,只要你不修改或者删除任何数值或
者子键,你就不会存在任何损害操作系统或者你的软件/硬件的配置的危险。实际
上,查看注册表可以学到很多东西。

SOFTWARE是HKEY_LOCAL_MACHINE键中一个子键,如果你检查你的计算机中的注册
表信息,你会发现其它的软件商已经使用了HKEY_LOCAL_MACHINE\SOFTWARE子键。

本文使用的示例应用程序使用了四级注册表,虽然它可以使用更多的子键嵌套。
我们将使用子键SOFTWARE\RegistryTest\Configuration\TestValue,TestValue
是我们想存储配置变量的地方。在我们的例子中,我们希望在SOFTWARE下找到嵌
套的RegistryTest,以及在RegistryTest下嵌套的Configuration,我们示例应用
程序的名称叫RegistryTest,我们想在一个Configuration字段中存储数据。

使用VJ6访问注册表
我们可以通过VJ6中的J/Direct来访问Windows API。但是在实践中我们不需要调
用API。VJ6本身包括了访问注册表的类,你可以通过这些类进行所有的注册表访
问。除非你的要求特别复杂。

这些类位于com.ms.wfc.app库中。Registry类可以很方便地得到注册表的根键,
在这里根键是一个RegistryKey对象。一个RegistryKey对象代表注册表中的一个
键或者子键,你可以使用RegKey类或者RegistryKey类,RegKey类提供的选择较少
,你只能访问四个根键:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER

HKEY_LOCAL_MACHINE以及HKEY_USERS。当使用RegKey类时,数据的类型被限制在
字符串、整型和字节类型。我们在本文中将使用RegistryKey类以及相关的
Registry类。

RegistryKey类被定义为final类型,因此你无法通过new这个操作符来声明一个实
例,你也不能继承它。为了得到RegistryKey的一个实例,你可以使用静态的
getBassClass,也可以使用 Registry类的成员函数。下面的代码对两种方法各举
一例。我喜欢使用Registry类中的一个成员函数,因为当我想对注册表立即进行
操作时可以节省一行代码。下面的例程首先获得RegistryKey类的一个实例,然后
对注册表立即进行一个操作。在这里是打开一个子键,如果这个子键不存在的话
,将创建一个子键。

//Creating an instance of RegistryKey class with the static getBaseKey() method;
 Performing
//an immediate action on a subkey takes an extra line of code.
RegistryKey objRegistryKey =
        RegistryKey.getBaseKey(HKEY_CURRENT_USER);
ObjRegistry.createSubkey(
        "Software\\RegistryTest\\Configuration");

//Creating an instance of the RegistryKey class with the CURRENT_USER member of
the
//Registry class. We create an instance of RegistryKey and perform an action
with just one
//line of code.
RegistryKey objRegistryKey = Registry.CURRENT_USER.
CreateSubKey)"Software\\RegistryTest\\Configuration");

RegistryKey类为创建、删除以及获取子键中的信息提供了强有力的功能,对于数
据值也具有相同的功能。

访问注册表中的数据值的代码也是非常简单的。如果子键存在,getSubKey将返回
一个Registry对象,否则将返回一个null。如果你只需要读取一个数据值并且需
要确保安全,getSubKey这个方法有一个布尔值的选项可以让你设置成只读的模式
。唯一的技巧就是对getValue返回的值进行类型转换。记住注册表是一个二进制
文件,你可以直接存储多种数据类型。getValue将返回一个对象并需要一个显式
的类型转换。在下面的代码中,数据值被转换成字符串的类型:


objRegistryKey = Registry.CURRENT_USER.getSubKey(
        "Software\\RegistryTest\\Configuration", true);
if (objRegistryKey = = null)
        alertNoSubKey("HKEY_CURRENT_USER\\Software" +
            "\\RegistryTest\\Configuration");
else
{
        strSetting = (String)objRegistryKey.getValue(
                "TestValue", "");
        objRegistryKey.close();
}

设置一个数据值的代码更加简单,不需要进行类型转换。记住把getSubKey中代表
只读参数的布尔变量改成false。此外,你将会得到一个WFC例外。如果你不传递
一个布尔值,则自动假设成false,可以对子键进行读/写访问。因此如果你愿意
的话,你可以不指定布尔值这个参数:

objRegistryKey = Registry.CURRENT_USER.getSubKey(
        "Software\\RegistryTest\\Configuration", false);
if (objRegistryKey = = null)
        alertNoSubKey("HKEY_CURRENT_USER\\Software" +
                        "\\RegistryTest\\Configuration");
else
{
        strSetting = (String)objRegistryKey.setValue(
                    "TestValue", "Some value");
    objRegistryKey.close();
}

删除一个子键更加简单。一样,确认把getSubKey布尔值这个参数设置成false或
者干脆不带这个参数:

objREgistryKey = Registry.CURRENT_USER.getSubKey(
        "Software\\RegistryTest\Configuration", false);
if (objRegistryKey = = null)
        alertNoSubKey ("HKEY_CURRENT_USER\\Software" +
                        "\\RegistryTest\\Configuration");
else
{
        strSetting =
            (String)objRegistryKey.DeleteValue ("TestValue");
        objRegistryKey.close ();
}

创建一个测试程序
本文章中的范例工程文件使用WFC生成一个对话框,用来测试对四个不同根键的访
问。程序在HKEY_CURRENT_USER根键下缺省创建一个叫做
\SOFTWARE\RegistryTest\Configuration的子键。如果你愿意的话可以改变这个
缺省设置。(在本文中讨论的范例程序可以从网上下载,详见本文最后)。


VJ6和MFC的一个好处就是你只需要编写很少几行的代码就能够创建一个对话框。
创建对话框的过程和VB的form designer是非常相似的。你从工具箱中把组件拖出
来然后把它丢到对话框中,你可以在代码以及/或者属性窗口中设置属性。


测试程序用一个集合框(group box)把收音机按钮框在一起,通过收音机按钮来
选择四个根键中的一个。此外还有命令行按钮,标签和编辑框。

虽然程序的代码好象又长又复杂,绝大多数都是用VJ6的Forms Designer进行设计
的。我增加了点击收音机按钮和命令行按钮所对应的事件。你可以用测试程序对
注册表的数据元素进行插入、更新以及删除操作。

警告:注意使用这个程序的风险性!不要删除或者修改除了测试程序缺省设置之
外的注册表项。

有三种操作注册表的私有方式:getSetting、saveSetting和deleteSetting。另
外还有两种私有方式提供额外支持:composeSubKey,它能够把编辑框中的文字组
合成为一个子键字符串;另一个是alertNoSubKey,当用户试图读取或者删除一个
不存在的子键时,它将产生一个对话框。

因为测试程序初始化了一个和Registry对象相关的RegistryKey对象,它在获取、
保存和删除设置时使用了一个switch语句,switch语句对选择特定根键所对应的
RegistryKey对象进行初始化。


无限的可能性
当今的用户希望软件易于定制,容易进行控制。注册表的设置允许你的应用程序
记住用户的个性设置。同时它还为应用程序的性能数据提供了一个存储的地点,
因此你的应用程序可以根据用户的需求进行自我优化。

比如,你可以在注册表中保存最近使用过的文件。Word和电子数据表能够这样,
你的应用程序也可以这样。你可以使用getValueCount来确定在你的最近使用列表
(MRU)中存在多少文件。这个计数器可以控制一个for的循环。有些应用程序设
计很巧妙,它们在MRU中使用文件名作为数据值,这就好象把它们放在变量赋值的
左边,而它们在数据值中输入了一个空白字符串。为什么?因为它们可以用一个
单一的命令使用getValueNames来返回他们MRU中的所有文件,而不需要用一个for
循环来列举数据值。就象我所说的那样--巧妙。此外,我是通过查看我的一台计
算机上的系统注册表的选项而学到这个技巧的。再次重复一遍,查看注册表经常
可以得到很大的收获。


当为不同的用户存储应用程序数据时,记住把HKEY_CURRENT_USER作为键。当你存
储那些对于一台计算机上的所有用户都必须相同的应用程序数据时,把
HKEY_LOCAL_MACHINE作为键。

注册表也可以用于不太重要的场合。它也是一个存储窗口位置和窗口大小设置、
URL等等数据的理想的位置。你可以在你的Java应用程序中使用系统注册表。
Visual J++ 6.0方便了对注册表的访问,当你访问注册表时只要遵守几条规则就
可以了。如果你胆敢于在注册表中冒险时,唯一的障碍就是你的独创性了。


测试程序清单:

import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;

/*
*This class can take a variable number of parameters on the command line.
Program
*execution begins with the main() method. The class constructor is not invoked
unless
*an object of type "Form1" created in the main() method
*/
public class frmRegistryTest extends Form
{
        //Root registry key the user chooses.
        RegistryKey objRootKey;
        //Name of root key, for error messages.

        Public frmRegistryTest()
        {
            //Required for Visual J++ Forms Designer support.
            initForm();

            //Initialize form values to use the HKEY_CURRENT_USER
            //registry key and the Software subkey.
            RbRoot2.setChecked(true);
            txtSubKey.setText("Software");
            txtApplication.setText("RegistryTest");
            txtSection.setText("Configuration");
            txtName.setText("TestValue");
            txtValue.setText("");
        }

        //The main entry point for the application
        //
        //@param args Array of parameters passed to the application via the
command line.
        public static void main(String args[])
        {
            Application.run(new frmRegistryTest());
        }

        private void btnGetSetting_click(Object sender, Event e)
        {
            txtValue.setText(getSetting());
        }

        private void btnSaveSetting_click(Object sender, Event e)
        {
            saveSetting();
        }

        private void btnDeleteSetting_click(Object sender, Event e)
        {
            deleteSetting();
        }

        private void alertNoSubKey(String strSubKey)
        {
            int intAction = MessageBox.show("Registry SubKey: '" +
                strSubKey + "' Not Found.", "No Registry Entry.");
            return;
        }

        private String composeSubKey()
        {

            //Takes text from edit boxes on the form.
            //Creates a registry SubKey string.
            String strSubKey;
            String strTemp;

            StrSubKey = txtSubKey.getText();

            //If the application name is not an empty string,
            //add it to the subkey.
            StrTemp = txtApplication.getText();
            If (strTemp.length() != 0)
                strSubKey = strSubKey + "\\" + strTemp;

            //If the section name is not an empty string,
            //add it to the subkey.
            StrTemp = txtSetion.getText();
            If (strTemp.length() != 0)
                strSubKey = strSubKey + "\\" + strTemp;

            return strSubKey;
        }

        private String getSetting()
        {
            String strSetting;

            //Set the registry to the appropriate SubKey.
            //Opens the SubKey in read-only mode for safety.
            RegistryKey objRegistryKey =
                ObjRootKey.getSubKey(composeSubKey(), true);
            if(objRegistryKey = = null)
                alertNoSubKey(strRootKey + composeSubKey());
            else
            {
                strSetting = objRegistryKey.getValue(
                    txtName.getText(), "").toString();
                objRegistryKey.close();
                return strSetting;
            }

            return "";
        }

        private void saveSetting()
        {
            //Set the registry to the appropriate SubKey.
            //Creates the SubKey,if it doesn't already exist.
            RegistryKey objRegistryKey =
                ObjRootKey.createSubKey(composeSubKey());
            objRegistryKey.setValue(txtName.getText(),
                                txtValue.getText());
            objRegistryKey.close();
        }

        private void deleteSetting()
        {
            //Set the registry to the appropriate SubKey.
            //Delete the SubKey value.
            RegistryKey objRegistryKey =
                ObjRootKey.getSubKey(composeSubKey(), false);
            If (objRegistryKey = = null)
                AlertNoSubKey(strRootKey + composeSubKey());
            else
            {
                objRegistryKey.deleteValue(txtName.getText());
                objRegistryKey.close();
                txtName.setText("");
                txtValue.setText("");
            }
        }

        private void rbRoot1_checkedChanged(Object source, Event e)
        {
            if (rbRoot1.getChecked())
            {
                objRootKey = Registry.CLASSES_ROOT;
                strRootKey = "HKEY_CLASSES_ROOT\\";
            }
        }

    private void rbRoot2_checkedChanged(Object source, Event e)
        {
            if (rbRoot2.getChecked())
            {
                objRootKey = Registry.CURRENT_USER;
                strRootKey = "HKEY_CURRENT_USER\\";
            }
        }

    private void rbRoot3_checkedChanged(Object source, Event e)
        {
            if (rbRoot3.getChecked())
            {
                objRootKey = Registry.LOCAL_MACHINE;
                strRootKey = "HKEY_LOCAL_MACHINE\\";
            }
        }

    private void rbRoot4_checkedChanged(Object source, Event e)
        {
            if (rbRoot4.getChecked())
            {
                objRootKey = Registry.USER;
                strRootKey = "HKEY_USER\\";
            }
        }
}

/**
* NOTE: The folowing code is required by the Visual J++
    * Forms Designer. It can be modified using the form editor. Do not modify
it using the code
* editor.
Container components = new Container();
GroupBox grpRoot = new GroupBox();
protected RadioButton rbRoot1 = new RadioButton();
protected RadioButton rbRoot2 = new RadioButton();
protected RadioButton rbRoot3 = new RadioButton();
protected RadioButton rbRoot4 = new RadioButton();
protected Button btnGetSetting = new Button();
protected Button btnSavesetting = new Button();
protected Button btnDeletesetting = new Button();
Label lblSubKey = new Label();
protected Edit txtSubKey = new Edit();
Label lblApplication = new Label();
Label lblSection = new Label();
Label lblName = new Label();
Label lblValue = new Label();
protected Edit txtApplication = new Edit();
protected Edit txtSection = new Edit();
protected Edit txtName = new Edit();
protected Edit txtValue = new Edit();

private void initForm()
{
        this.setText("Registry Test");
        this.setAutoScaleBaseSize(13);
        this.setClientSize(new Point(500, 190));

        grpRoot.setLocation(new Point(5, 1));
        grpRoot.setSize(new Point(160, 102));
        grpRoot.setTabIndex(0);
        grpRoot.setTabStop(false);
        grpRoot.setText("Root Key");

        rbRoot1.setLocation(new Point(10, 20));
        rbRoot1.setSize(new Point 148, 12));
        rbRoot1.setTabIndex(0);
        rbRoot1.setText("HKEY_CLASSES_ROOT");
        rbRoot1.addOnCheckedChanged(new
EventHandler(this.rbRoot1_checkedChanged());

        rbRoot2.setLocation(new Point(10, 40));
        rbRoot2.setSize(new Point 148, 12));
        rbRoot2.setTabIndex(1);
        rbRoot2.setText("HKEY_CURRENT_USER");
        rbRoot2.addOnCheckedChanged(new
EventHandler(this.rbRoot2_checkedChanged());

        rbRoot3.setLocation(new Point(10, 60));
        rbRoot3.setSize(new Point 148, 12));
        rbRoot3.setTabIndex(2);
        rbRoot3.setText("HKEY_LOCAL_MACHINE");
        rbRoot3.addOnCheckedChanged(new
EventHandler(this.rbRoot3_checkedChanged());

        rbRoot4.setLocation(new Point(10, 80));
        rbRoot4.setSize(new Point 148, 12));
        rbRoot4.setTabIndex(3);
        rbRoot4.setText("HKEY_USERS");
        rbRoot4.addOnCheckedChanged(new
EventHandler(this.rbRoot4_checkedChanged());

        btnGetSetting.setLocation(new Point(176, 8));
        btnGetSetting.setSize(new Point(74, 25));
        btnGetSetting.setTabIndex(10);
        btnGetSetting.setText("Get Setting");
        btnGetSetting.addOnClick(new EventHandler(this.btnGetSetting_click));

        btnGetSetting.setLocation(new Point(176, 40));
        btnGetSetting.setSize(new Point(74, 25));
        btnGetSetting.setTabIndex(11);
        btnGetSetting.setText("Save Setting");
        btnGetSetting.addOnClick(new EventHandler(this.btnGetSetting_click));

        btnGetSetting.setLocation(new Point(176, 72));
        btnGetSetting.setSize(new Point(74, 25));
        btnGetSetting.setTabIndex(12);
        btnGetSetting.setText("Delete Setting");
        btnGetSetting.addOnClick(new EventHandler(this.btnGetSetting_click));

        lblSubKey.setLocation(new Point(7, 108));
        lblSubKey.setSize(new Point(80, 12));
        lblSubKey.setTabIndex(1);
        lblSubKey.setTabStop(false);
        lblSubKey.setText("");

        txtSubKey.setLocation(new Point(7, 124));
        txtSubKey.setSize(new Point(490, 20);
        txtSubKey.setTabIndex(4);
        txtSubKey.setText("");

        lblApplication.setLocation(new Point(7, 144));
        lblApplication.setSize(new Point(80, 12));
        lblApplication.setTabIndex(2);
        lblApplication.setTabStop(false);
        lblApplication.setText("Application:");

        lblSection.setLocation(new Point(114, 144));
        lblSection.setSize(new Point(80, 12));
        lblSection.setTabIndex(3);
        lblSection.setTabStop(false);
        lblSection.setText("Section");

        lblName.setLocation(new Point(222, 144));
        lblName.setSize(new Point(80, 12));
        lblName.setTabIndex(9);
        lblName.setTabStop(false);
        lblName.setText("Name:");

        lblValue.setLocation(new Point(329, 144));
        lblValue.setSize(new Point(80, 12));
        lblValue.setTabIndex(13);
        lblValue.setTabStop(false);
        lblValue.setText("Value:");

        txtApplication.setLocation(new Point(7, 157));
        txtApplication.setSize(new Point(80, 12));
        txtApplication.setTabIndex(5);
        txtApplication.setText("");

        txtSection.setLocation(new Point(114, 157));
        txtSection.setSize(new Point(100, 20));
        txtSection.setTabIndex(6);
        txtSection.setText("");

        txtName.setLocation(new Point(222, 157));
        txtName.setSize(new Point(100, 20));
        txtName.setTabIndex(7);
        txtName.setText("");

txtValue.setLocation(new Point(329, 157));
txtValue.setSize(new Point(100, 20));
txtValue.setTabIndex(8);
txtValue.setText("");

this.setNewControls(new Control[]{
        txtSubKey;
        lblSubKey;
        txtValue;
        txtName;
        txtSection;
        txtApplication;
        lblValue;
        lblName;
        lblSection;
        lblApplication;
        btnDeleteSetting;
        btnSaveSetting;
        btnGetSetting;
        grpRoot});
grpRoot.setNewControls(new Control[]{
        rbRoot4,
        rbRoot3,
        rbRoot2,
        rbRoot1});
}
//NOTE: End of Forms Designer support code.

Public static class ClassInfo extends Form.ClassInfo
{
}
}


--


   我想超越这平凡的生活,注定我暂时漂泊!

   我无法停止我内心的狂热,对未来的执着!

※ 修改:·Jobs 於 Feb 19 17:53:36 修改本文·[FROM: 192.168.18.111]
※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.18.111]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店