[MFC]文档字符串、HKEY_CLASSES_ROOT注册表、.reg注册表文件

来源:互联网 发布:彻底掌握c语言 编辑:程序博客网 时间:2024/06/05 21:12

1. 文档字符串的定义:

    1) 也是LoadFrame可以加载的第四种资源(图标、菜单、加速键之外的第四种资源);

    2) 定义方式例如:

STRINGTABLE PRELOAD DISCARDABLE BEGIN    IDR_MAINFRAME           "SdiSquares\n\nSdiSqu\nSdiSqu Files (*.sqr)\n.sqr\nSdiSquares.Document\nSdiSqu Document"END
         i. 定义使用关键字STRINGTABLE;

         ii. 里面的那条字符串都要用一条资源ID来标识,就像菜单的菜单项一样,每一项都要用一个ID来标识;

    3) 其中的字符串是由换行符\n相互隔开的7个子字符串构成,如果哪一个字符串为空也必须用两个\n(中间什么字符都没有)包夹在一起,标识中间的字符串为空;

    4) 7个字符串的含义(从头到尾):

*1. 框架窗口标题栏中的标题,一般用来指示应用程序名,例如:Microsoft Word,中间可以带空格

*2. 分配给未命名的新创建文档的名字,如果该字符串为空将默认为"Untitled"

!!在创建或打开一个文档后程序标题栏会显示"文档名-程序名",程序名就是第一个子字符串,文档名可以是已存在的文档的名称也可以是默认的Untitled(即第2个子字符串);

*3. MDI文档类型过滤器,在SDI中用不到,可以为空;

*4. SDI文档类型过滤器,会在CFileDialog的文档过滤器列表中显示,例如:Doc Files(*.doc);

!!!5和6会在注册表中注册时起到作用,后面会具体讲解注册表的相关内容;

*5. 文档的默认扩展名(在用户没输入后缀的情况下自动添加),例如:.txt就是合法的,注意,一定要加.

*6. 注册表文档类型:也成为注册表ID;

!!!

*7. 文档类型描述:文档的属性选项卡中会显示出来的供人阅读的名字,可以比较长,可以包含空格,主要作用是简短地解释文档的类型,在注册表中是注册表ID对应的描述性字符串;


2. 使用GetDocString来获取文档字符串的各个子字符串:

    1) 函数原型:vritual BOOL CDocTemplate::GetDocString(CString& rString, enum DocStringIndex index) const;

    2) rString用于接受想获得的字符串;

    3) index使用枚举类型定义的索引值,它们都已CDocTemplate::作为前缀,这里按照子字符串的排列顺序给出:

windowTitle:标题

docName:默认的文档名

fileNewName:MDI文档类型过滤器

filterName:SDI文档类型过滤器

filterExt:默认扩展名

regFileTypeID:文档在注册表中的名称,即注册表ID

regFileTypeName:最后一个子字符串,即注册表ID对应的描述性字符串

    4) 示例:pDocTemplate->GetDocString(strBuffer, CDocTemplate::filterExt); // strBuffer中将保存默认文档扩展名;


3. HKEY_CLASSES_ROOT——热键关联注册表(设定文件的默认图标和打开程序):

    1) Windows的注册表可以使用regedit.exe打开并进行编辑;

    2) 在regedit编辑器的最左侧可以看到系统中所有的热键目录表;

    3) 热键HKEY的概念:

         i. 即Hot Key,就是一些快捷操作;

         ii. 最典型的快捷操作介绍:比如在Linux系统中,你要打开一个文档,必须在命令行上键入打开文档的程序以及目标文档的名称,回车之后才能打开,但是Windows中就只要双击文档图标就能用默认的程序来打开它,非常方便;

!!但不过这些方便都是需要在注册表中添加相关信息后才能达到这样的效果,否则就还是跟Linux一样,手动在命令行上键入程序和文档回车后才行;

    4) ROOT表示这是某种类型的HKEY的根目录,该种类型的所有HKEY都存放在这个目录下;

    5) HEKY_CLASSES_ROOT表示跟文件类型相关的热键根目录,比如其中最主要的就是文档类型,里面保存着关于各种文档类型的热键,比如.txt文档的默认打开程序、.doc文档的默认文档图标等;

    6) Windows使用键值的方式来管理热键注册表,所有的快捷操作都需要通过定义键值并且把键值添加(注册)到注册表之后才能生效;

    7) Windows用类似目录的形式来实现键值管理,一个键可以有自己的子键,那么就可以说母键是子键的上级目录,子键是母键的子目录,但这是一种说法,实际上在底层并不是使用目录来实现的,只不过这样认为可以让问题更简单,而实际上在regedit中也是用目录的形式来展示母键与子键的关系的;

!在regedit左侧的目录表中可以看到所有的键的图标都是文件夹,文件夹打开还有别的文件夹(子键),整个注册表以树形目录的形式来展示;

!没用鼠标选中一个键(一个文件夹图标)就会在右侧的视图中看到改建的值(数值名称-类型-数据),其中数据就是键的值;

    8) 特殊键:

         i. 是指一些名称特殊的键,如果将一个键命名为这些特殊的名称,Windows会用特定的方式对待和解释它们;

         ii. 首先是后缀键,就是以'.'开头的键,Windows会将这样的键当做文件的后缀名,当用户双击这种后缀名的文件时Windows就会根据该键的值做一些相应的处理;

         iii. defaulticon:该键将定义默认图标,比如在.txt键下建立子键defaulticon,然后给defaulticon的值设为一个图标的绝对路径,那么所有以.txt为后缀的文档都会以该图标作为自己的默认图标;

         iv. shell:该键将定义和命令解释器(类似于后台运行的cmd.exe,你在图形界面上双击打开一个应用程序实际上实在后台的命令解释器中输入了该程序的名称并回车才打开的)相关的东西;

         v. shell键下可以定义子键open:用来定义如何用命令解释器打开一个文档或程序;

         vi. open子键下还可以定义子键command:表示用一条命令来打开一个文档或程序,command键的值就是指定应用程序的绝对路径

!!所以shell\open\command键就是指使用默认的外壳命令来打开某种类型的文件,那么.txt\shell\open\command键就是指用指定的外壳命令来打开.txt文件了;

         vii. command键的值:格式是"程序的绝对路径 %数字",数字可以是0/1/2,其中0表示不启用,1表示启用,2表示二进制(该含义我到现在也不明白,但反正也用不上),启用就表示启用默认打开程序的功能,因此数字一定是1!!

    9) 文档类型ID:

         i. 通常并不会直接在后缀键下直接定义defualticon、shell\open\command等键,原因很简单,那就是有可能几个不同后缀的文件用同一个程序打开,如果这些子键都定义在后缀键下的话,那么每一个后缀键都要重复定义一遍这些子键,这不仅非常不方便,而且如果哪一天默认打开的程序发生改动(名称发生变化、路径发生变化),那么就得到每一个后缀键的子键中进行修改,工作量非常大;

         ii. 标准的做法——键的关联:Windows允许将一个键关联到另一个键,即用一个键的名称来作为另一个键的值,那么在对解析一个键的时候就会找到它的值所对应的键并解析这个关联的键,例如.doc、.docx的值都为Word.Document,然后在Word.Docment键中定义defualticon、shell\open\command等键,那么就能实现.doc和.docx都用Word打开的目的了;

         iii. 上面的Word.Document就是后缀键的值,后缀键的值的学名就是文档类型ID,也就是说专业标准的做法就是为每种后缀键定义相应的文档类型ID,然后再在文档类型ID中定义相关的热键操作,以后文档类型ID就简称为文档类型了;

         iv. 文档类型的命名规则:没有严格的命名规则,可以任意取名,但不过有约定俗称的规范,规范就是"默认打开程序名.文件类型名",比如Word.Document,就是用Word打开的文档,Vim.Initfile就是用Vim打开的初始化文件等,这样见名知意,习惯非常良好,为未来的注册表管理带来很大的方便;

    10) 和文档字符串的关系:

         i. 第5个子字符串filterExt将作为后缀键;

         ii. 第6个字符串regFileTypeID将作为文件类型ID键;

         iii. 最后一个字符串regFileTypeName将作为文件类型ID键的键值,用来解释该文件类型是什么东西;


4. .reg注册表文件:

    1) 如果要在注册表中添加新的键值则可以直接在regedit里操作,右键添加项目等,但最方便的也最适合应用程序管理的方法是直接编写.reg注册表文件;

    2) 可以直接在.reg文件中定义要添加的键值信息,保存后直接双击.reg文件就可以将文件中的键值信息合并到Windows注册表中了;

!!注意:如果.reg中定义的键和注册表中已有的键重复则会覆盖合并,因此在每次双击.reg文件进行合并时Windows都会弹出消息框警告可能会产生的覆盖,待用户十分确定之后再决定是否合并;

    3) .reg文件的书写格式:

         i. 第一行必须是关键字REGEDIT,表示这是一个注册表文件,需要用regedit.exe来执行合并

         ii. 注释使用分号;

         iii. 正文部分就是"键 = 值",例如一个典型的注册表文件:

REGEDIT; This .REG file may be used by your SETUP program.;   If a SETUP program is not available, the entries below will be;   registered in your InitInstance automatically with a call to;   CWinApp::RegisterShellFileTypes and COleObjectFactory::UpdateRegistryAll.HKEY_CLASSES_ROOT\.sqr = SdiSquares.DocumentHKEY_CLASSES_ROOT\SdiSquares.Document\shell\open\command = I:\samp\Visual Studio 6.0\MFC\Code\Chap09\SdiSquares\Release\SdiSquares.exe %1HKEY_CLASSES_ROOT\SdiSquares.Document\shell\open\ddeexec = [open("%1")]HKEY_CLASSES_ROOT\SdiSquares.Document\shell\open\ddeexec\application = SDISQUARES    ; note: the application is optional    ;  (it defaults to the app name in "command")HKEY_CLASSES_ROOT\SdiSquares.Document = SdiSqu Document


!!.reg文件一般用于安装程序,一般会在安装程序中执行该文件以完成应用程序的注册;


5. MFC对注册表的支持:

    1) 首先在用Wizzard创建应用程序时就可以预先生成程序的注册表文件;

    2) 在创建MFC[.exe]程序的第4步中打开Advanced属性框,可以在里面设置应用程序的7个文档字符串,设置完毕后就会自动生成一个.reg注册表文件;

    3) 如果后面在程序的资源编辑器中修改文档字符串,则.reg也会自动被Visual C++修改;

    4) 在InitInstance中自动完成对程序的注册:

         i. 之前将InitInstance时还漏掉的两条函数调用:

...AddDocTemplate(pDocTemplate);// Enable DDE Execute openEnableShellOpen();RegisterShellFileTypes(TRUE);// Parse command line for standard shell commands, DDE, file openCCommandLineInfo cmdInfo;ParseCommandLine(cmdInfo);...
!!那就是EnableShellOpen和RegisterShellFileTypes函数,它们在AddDocTemplate和ParseCommandLine之间调用;

         ii. EnableShellOpen:void CWinApp::EnableShellOpen(); // 开启双击文档用此应用程序打开的功能

         iii. void CWinApp::RegisterShellFileTypes(BOOL bCompat = FALSE); // 根据文档字符串的信息来为应用程序在注册表中注册,参数必须为TRUE才能注册!

!!只有在注册之后才能将双击文件图标的操作转换为Shell命令打开;


6. 支持MDI程序的特殊热键——ddeexec:

    1) 对于MDI程序,在使用Wizzard自动生成.reg文件,以及用RegisterShellFileTypes时都会多加一个键,这就是ddeexec;

    2) ddeexec其实是DDE Execution的缩写,而DDE就是Do Data Exchange的缩写;

    3) DDE的作用就是支持在一个程序中同时打开多个文档;

    4) 在应用程序已经打开一个文档的情况下再双击打开一个文档时DDE会给已存在的应用程序实例发送一个Open命令以及待打开的文档的参数,之后DDE再间接调用应用程序的OnOpenDocument来打开第二个文档并显示出来,从而避免了在开启一个应用程序实例来打开第二个文档,这就达到了一个程序实例打开多个文档的目的;

    5) 现在再来看一下ddeexec键是如何添加的,看一个例子:

HKEY_CLASSES_ROOT\SdiSquares.Document\shell\open\ddeexec = [open("%1")]HKEY_CLASSES_ROOT\SdiSquares.Document\shell\open\ddeexec\application = SDISQUARES
!这就是上面出现过的例子,ddeexec必然是shell\open的子键,因为它是一种打开命令热键,它的值必须设为[open("%1")],[]表示该值是该键的一个函数调用,因此这里的[open]就是键ddeexec的一个函数调用,即执行ddeexec.open函数,函数的参数都是字符串,因此用""括起来,%1就表示命令行的第1号参数,第0号参数是打开程序本身,第0号参数就待打开的文件名(绝对路径);

!!ddeexec的值就代表了利用DDE向应用程序发出一条Open命令,并且Open的对象也在参数给出了;

!接着就是ddeexec的子键application,该键就表示DDE发送Open命令的对象程序,也就是该文档类型默认的打开程序了(只不过是用DDE间接打开的MDI程序而已),这里的值必须是程序的绝对路径!!但是不用加“%数字”!


0 0
原创粉丝点击