之前写过一个文章,介绍在windows下文件关联的实现机制《【MFC应用】文件关联》,这篇文章是介绍利用注册表实现文件关联的原理的,当初本来计划再写一篇文章,介绍MFC下的实现的,结果给忘了,唉,这脑子~~~~ 今天看到有网友留言给我,才突然发现还没写过MFC的实现,所以,今天补上 ^_^
上一篇曾经介绍过,其实要实现文件关联,关键就是对注册表的操作。在MFC中,有个叫做CRegKey的类,封装了对注册表的操作,下面对这个类简单介绍一下:
1.简介
CRegKey提供了对系统注册表的操作方法,通过CRegKey类,可以方便的打开注册表的某个分支或子键(CRegKey::Open),可以方便的修改一个键的键值(CRegKey::SetValue),也可以查询某个键的键值(CRegKey::QueryValue),操作完成之后,可以关闭子键(CRegKey::Close)。
要想使用CRegKey类,需要包含头文件atlbase.h
2.常用操作方法
1) 打开需要查询或修改的注册表键
LONG Open( HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired = KEY_ALL_ACCESS );
hKeyParent参数指定了待打开的注册表键的句柄,常用的可选值为
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
以上四个值分别代表了注册表中最主要的四个分支;
lpszKeyName参数指定了在hKeyParent下需要打开的项的名字;
samDesired参数指定了打开该项后所拥有的权限,默认为KEY_ALL_ACCESS,表示拥有对该分支的所有操作权,包括读和写等。
举例:
1: CRegKey myKey;2: if(myKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows") != ERROR_SUCCESS)
3: {4: AfxMessageBox("Error open reg key!!");
5: }
2) 查询注册表项中的某个键的键值
LONG QueryValue( DWORD& dwValue, LPCTSTR lpszValueName );
LONG QueryValue( LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount )
查询键值提供了两种形式,分别用来获取数值类型的值和字符串类型的值。在上面的形式中,第一种用于获取数值类型的值,第二种用于获取字符串类型的值。
lpszValueName参数用来指定键的名称,dwValue和szValue用于保存键值,而pdwCount用来控制获取到的字符串值的长度
举例:
比如,假设要获得windowx系统默认的桌面壁纸的搜索路径,由于这个路径保存在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion这一项的WallPaperDir键内,如下图

所以,可以用以下的代码来实现:
1: CRegKey myKey;2: if(myKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion") != ERROR_SUCCESS)
3: AfxMessageBox("Error open reg key!!!");
4: else
5: {6: char szPath[MAX_PATH];
7: DWORD dwLen = myKey.QueryValue(szPath, "WallPaperDir", MAX_PATH);
8: }另外,如果我们想查询某个项的默认键值该怎么办呢?只需要将lpszValueName参数写为空字符串就好了。比如现在想看一下.txt类型的文件的关联程序是谁,我们需要首先在HKEY_CLASSES_ROOT下找到.txt项,然后看它的默认键值是多少:

示例代码如下:
1: CRegKey myKey;2: if(myKey.Open(HKEY_CLASSES_ROOT, ".txt") != ERROR_SUCCESS)
3: AfxMessageBox("Error open key!!!");
4: else
5: {6: char szFileType[255];
7: DWORD dwLen = myKey.QueryValue(szFileType, "", sizeof(szFileType));
8: }3) 添加或修改键值
LONG SetValue( DWORD dwValue, LPCTSTR lpszValueName );
LONG SetValue( LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL );
LONG SetValue( HKEY hKeyParent, LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL );
添加键值函数提供了三种形式,前两种分别用来向当前已经打开的这个项中添加DWORD类型的键、字符串类型的键,最后一种形式的函数,可以在某个特定的分支线下的某个特定的项内添加一个键。如果lpszKeyName指定的键不存在,则添加这个键,否则,就是修改已经存在的键的键值。另外需要注意的是,最后一种形式的SetValue函数,如果lpszKeyName所指定的项不存在,则SetValue函数会返回错误,而不会添加一个项。
示例,比如现在要给IE的工具栏设置一个背景图片,可以在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar项下面新建一个BackBitmap的字符串键,并制定背景图片的位置,代码如下:
1: CRegKey myKey;2: if(myKey.Open(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\Toolbar") != ERROR_SUCCESS)
3: AfxMessageBox("error open reg key!!!");
4: else
5: {6: myKey.SetValue("C:\\WINDOWS\\Web\\Wallpaper\\Bliss.bmp", "BackBitmap");
7: }这样,IE的背景图片就被设置成了C:\WINDOWS\Web\Wallpaper\Bliss.bmp
4) 删除键值
LONG DeleteValue( LPCTSTR lpszValue );
这个函数比较简单,它会删除lpszValue参数指定的键。
5) 新建项
LONG Create( HKEY hKeyParent, LPCTSTR lpszKeyName, LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE, REGSAM samDesired = KEY_ALL_ACCESS, LPSECURITY_ATTRIBUTES lpSecAttr = NULL, LPDWORD lpdwDisposition = NULL );
Create函数用于创建一个项,它可以在hKeyParent指定的分支下,创建一个名为lpszKeyName的项,后面几个参数一般用默认的即可。
比如,现在要建立一个新的文件类型.spj的关联方式,首先需要在HKEY_CLASSES_ROOT下建立一个名为.spj的项,代码如下:
1: CRegKey myKey;2: if(myKey.Create(HKEY_CLASSES_ROOT, ".spj") != ERROR_SUCCESS)
3: AfxMessageBox("error create key!!!");
4: else
5: AfxMessageBox("create key ok!");
6) 删除项
LONG DeleteSubKey( LPCTSTR lpszSubKey );
该函数可以删除名为lpszSubKey的项,以及该项下的所有的键。注意,被删除的项不能含有子项!可以通过另外一个函数LONG RecurseDeleteKey( LPCTSTR lpszKey );删除某个项以及该项下的所有内容。
7) 关闭注册表
LONG Close( );
关闭注册表时,之前所做的修改才会被保存到硬盘。或者,也可以使用LONG RegFlushKey( HKEY hKey ); 函数在需要的时候将所做的修改及时写入硬盘。
OK,有关CRegKey的介绍先告一段落。下面接着进行MFC下如何进行文件关联的操作。
其实,只要知道了CRegKey类的使用方法,文件关联的操作也就不难了。下面贴出来一个简单的文件关联的类,抛砖引玉:
1: // RegRelateExt.h: interface for the CRegRelateExt class.
2: //
3: //////////////////////////////////////////////////////////////////////
4: 5: #if !defined(AFX_REGRELATEEXT_H__6DE7E979_9011_4639_967A_D8817DF4DE44__INCLUDED_)
6: #define AFX_REGRELATEEXT_H__6DE7E979_9011_4639_967A_D8817DF4DE44__INCLUDED_
7: #include "ATLBASE.h"
8: 9: #if _MSC_VER > 1000
10: #pragma once
11: #endif // _MSC_VER > 1000
12: 13: class CRegRelateExt : public CRegKey
14: {15: public:
16: CRegRelateExt();17: CRegRelateExt(CString FileExt, CString RelateExe = "LibMaker.exe");
18: virtual ~CRegRelateExt();
19: BOOL Check(); 20: BOOL Check(CString FileExt); 21: BOOL Set(CString FileExt, CString ShellCmd); 22: BOOL Delete(CString FileExt); 23: 24: private:
25: BOOL m_IfRelated; 26: 27: CString m_RegClass; 28: CString m_RelateExe; 29: }; 30: 31: #endif // !defined(AFX_REGRELATEEXT_H__6DE7E979_9011_4639_967A_D8817DF4DE44__INCLUDED_)
上面是头文件,定义了CRegRelateExt类,这个类提供了几个操作方法,比如:Check用于检查某个扩展名是否与指定程序关联;Set用于将某个扩展名的文件与指定程序进行关联;Delete用于删除某个文件类型的关联。
1: // RegRelateExt.cpp: implementation of the CRegRelateExt class.
2: //
3: //////////////////////////////////////////////////////////////////////
4: 5: #include "stdafx.h"
6: #include "LibMaker.h"
7: #include "RegRelateExt.h"
8: 9: #ifdef _DEBUG10: #undef THIS_FILE
11: static char THIS_FILE[]=__FILE__;
12: #define new DEBUG_NEW
13: #endif
14: 15: //////////////////////////////////////////////////////////////////////
16: // Construction/Destruction
17: //////////////////////////////////////////////////////////////////////
18: 19: CRegRelateExt::CRegRelateExt() 20: { 21: m_IfRelated = FALSE; 22: } 23: 24: CRegRelateExt::CRegRelateExt(CString FileExt, CString RelateExe) 25: { 26: m_RelateExe = RelateExe; 27: Check(FileExt); 28: } 29: 30: BOOL CRegRelateExt::Check() 31: {32: return m_IfRelated;
33: } 34: 35: BOOL CRegRelateExt::Check(CString FileExt) 36: {37: if(m_RelateExe.IsEmpty())
38: return FALSE;
39: 40: if(Open(HKEY_CLASSES_ROOT, FileExt, KEY_READ) != ERROR_SUCCESS)
41: m_IfRelated = FALSE; 42: 43: DWORD ValueLen = MAX_PATH; 44: TCHAR Value[MAX_PATH];45: if(QueryValue(Value, "", &ValueLen) != ERROR_SUCCESS)
46: m_IfRelated = FALSE; 47: Close(); 48: m_RegClass = Value; 49: 50: if(Open(HKEY_CLASSES_ROOT, m_RegClass + "\\shell\\open\\command", KEY_READ) != ERROR_SUCCESS)
51: m_IfRelated = FALSE; 52: 53: ValueLen = MAX_PATH;54: if(QueryValue(Value, "", &ValueLen) != ERROR_SUCCESS)
55: m_IfRelated = FALSE; 56: 57: Close(); 58: CString CmdLine = Value;59: if(CmdLine.Find(m_RelateExe) != -1)
60: m_IfRelated = TRUE;61: else
62: m_IfRelated = FALSE;63: return m_IfRelated;
64: } 65: 66: BOOL CRegRelateExt::Delete(CString FileExt) 67: {68: if(FileExt.IsEmpty())
69: return FALSE;
70: 71: if(Open(HKEY_CLASSES_ROOT, FileExt, KEY_READ) != ERROR_SUCCESS)
72: return FALSE;
73: 74: DWORD ValueLen = MAX_PATH; 75: TCHAR Value[MAX_PATH];76: if(QueryValue(Value, "", &ValueLen) != ERROR_SUCCESS)
77: return FALSE;
78: Close(); 79: 80: Attach(HKEY_CLASSES_ROOT);81: if(RecurseDeleteKey(Value) != ERROR_SUCCESS)
82: return FALSE;
83: 84: if(RecurseDeleteKey(FileExt) != ERROR_SUCCESS)
85: return FALSE;
86: 87: return TRUE;
88: } 89: 90: BOOL CRegRelateExt::Set(CString FileExt, CString ShellCmd) 91: {92: if(FileExt.IsEmpty() || ShellCmd.IsEmpty())
93: return FALSE;
94: 95: m_RelateExe = ShellCmd;96: m_RegClass = "S+core Arch File";
97: Delete(FileExt); 98: 99: if(Create(HKEY_CLASSES_ROOT, FileExt) != ERROR_SUCCESS)
100: return FALSE;
101: if(SetValue(HKEY_CLASSES_ROOT, FileExt, m_RegClass) != ERROR_SUCCESS)
102: return FALSE;
103: if(Create(HKEY_CLASSES_ROOT, m_RegClass) != ERROR_SUCCESS)
104: return FALSE;
105: if(SetValue(HKEY_CLASSES_ROOT, m_RegClass, "S+core Archive File") != ERROR_SUCCESS)
106: return FALSE;
107: if(SetValue((DWORD)0x08, "BrowserFlags") != ERROR_SUCCESS)
108: return FALSE;
109: if(SetValue((DWORD)0x00, "EditFlags") != ERROR_SUCCESS)
110: return FALSE;
111: if(SetValue(HKEY_CLASSES_ROOT, m_RegClass, "S+core Archive File") != ERROR_SUCCESS)
112: return FALSE;
113: if(Create(HKEY_CLASSES_ROOT, m_RegClass + "\\DefaultIcon") != ERROR_SUCCESS)
114: return FALSE;
115: if(SetValue(HKEY_CLASSES_ROOT, m_RegClass + "\\DefaultIcon", ShellCmd + ",1") != ERROR_SUCCESS)
116: return FALSE;
117: if(Create(HKEY_CLASSES_ROOT, m_RegClass + "\\shell") != ERROR_SUCCESS)
118: return FALSE;
119: if(Create(HKEY_CLASSES_ROOT, m_RegClass + "\\shell\\open") != ERROR_SUCCESS)
120: return FALSE;
121: if(Create(HKEY_CLASSES_ROOT, m_RegClass + "\\shell\\open\\command") != ERROR_SUCCESS)
122: return FALSE;
123: if(SetValue(HKEY_CLASSES_ROOT,m_RegClass + "\\shell\\open\\command", ShellCmd + " \"%1\"") != ERROR_SUCCESS)
124: return FALSE;
125: m_IfRelated = TRUE;126: return TRUE;
127: } 128: 129: CRegRelateExt::~CRegRelateExt() 130: { 131: 132: }