VC的碰到的问题

   在用VC过程中,会碰到许许多多繁不胜繁的小问题,我想是其中很多都出在C++语言复杂度、API,MFC类库的繁琐,以及函数参数类型的不一致,其它的还有宏,C和C++外部函数的共享,程序的compile,link等等.
   
   今天碰到的二个问题,一个属于函数参数类型的不正确,一个属于链接lib时出现Error的问题.

   一、第一个问题,我想遍历注册表,用API函数RegEnumValue可以实现遍历,但是会出现:有些能遍历,有些却不能遍历,看程序:
   这是我第一次写的程序:
    
 1 None.gif HKEY regOldHKey;
 2 None.gif
 3 None.gif // Open Register Key
 4 None.gif if (::RegOpenKeyEx(HKEY_CURRENT_USER, " Software\\OKI\\CCons33\\UNITTYPE " , 0 ,KEY_ALL_ACCESS, & regOldHKey) == ERROR_SUCCESS)
 5 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 6InBlock.gif    long lResult;
 7InBlock.gif    DWORD dwIndex;
 8InBlock.gif    CHAR* tcKeyName = new CHAR[MAX_PATH];
 9InBlock.gif    DWORD dwKeyNameLen = MAX_PATH;
10InBlock.gif    DWORD lpSize,nType;
11InBlock.gif    LPBYTE newByte = new BYTE[MAX_PATH]
12InBlock.gif    while(TRUE)
13ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
14InBlock.gif        //circulate the Register
15InBlock.gif        lResult=RegEnumValue(regOldHKey,dwIndex,tcKeyName,&dwKeyNameLen,NULL,NULL,NULL,NULL);
16InBlock.gif        if(lResult!=ERROR_SUCCESS)
17InBlock.gif            break//if the End then break;
18InBlock.gif
19InBlock.gif        //Use the key Get the value
20InBlock.gif        if(::RegQueryValueEx(regOldHKey,(LPCTSTR)tcKeyName,NULL,&nType,newByte,&lpSize)==ERROR_MORE_DATA)
21ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
22InBlock.gif            newByte=(LPBYTE)"NULL";
23ExpandedSubBlockEnd.gif        }

24InBlock.gif
25InBlock.gif        //Print the key and the value
26InBlock.gif        cout<<"Key:"<<(LPCTSTR)tcKeyName;
27InBlock.gif        cout<<"\t";
28InBlock.gif        cout<<"Value:"<<(LPCTSTR)newByte;
29ExpandedSubBlockEnd.gif    }

30ExpandedBlockEnd.gif}

   这个程序有几个问题,根本无法进行遍历!
   首先,看看RegEnumValue的函数原型:
   
None.gif LONG RegEnumValue(
None.gif  HKEY hKey,
None.gif  DWORD dwIndex,
None.gif  LPTSTR lpValueName,
None.gif  LPDWORD lpcValueName,
None.gif  LPDWORD lpReserved,
None.gif  LPDWORD lpType,
None.gif  LPBYTE lpData,
None.gif  LPDWORD lpcbData
None.gif);
None.gif

 MSDN上面提到dwIndex用之前必须要进行初始化,dwIndex在遍历过程中起到了一个计数器的作用,如果不初始化程序编译的时候也会出现警告
   所以,第七行应该对dwIndex进行初始化: DWORD dwIndex=0;
   
   第二点,也是我碰到问题才发现的,凡是参数涉及到指针,而实参本身并不是指针类型,需要通过前面加上&地址符来作参数的,如上述的 dwKeyNameLen,nType,lpSize等等,API会对其进行变动,一般调用一次没什么问题,但在这里是循环,可能上次写进去的值会影响到下次执行。
   就比如拿dwKeyNameLen来说,作字符串缓冲区用。第一次执行是可以的,第一次执行后它的值是lpData字符串的长度。第二次也是可以的,因为第二次遍历lpData的长度小于第一次,但第三次lpData字符串长度比第一次还要长。这时RegEnumValue就会返回一个ERROR_MORE_DATA返回值,并跳出循环。(也就是说,缓冲区的长度满足不了lpData字符串).
   与此相关的问题lpSize也是一样,当在RegQueryValueEx函数中,lpSize表示的长度不够时,函数就会拒绝写入newByte.并返回ERROR_MORE_DATA.
   So,对于以上问题,我们需要在下一次遍历前再次初始化dwKeyNameLen与newByte的值
   dwKeyNameLen=MAX_PATH;
   newByte=MAX_PATH;

   最后一个问题,dwIndex作为计数器,没有在最后执行自增操作,这样会导致死循环.

   正确的代码如下:
   
 1 None.gif         HKEY regOldHKey;
 2 None.gif
 3 None.gif         // Open Register Key
 4 None.gif          if (::RegOpenKeyEx(HKEY_CURRENT_USER, " Software\\OKI\\CCons33\\UNITTYPE " , 0 ,KEY_ALL_ACCESS, & regOldHKey) == ERROR_SUCCESS)
 5 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
 6InBlock.gif            long lResult;
 7InBlock.gif            DWORD dwIndex=0;
 8InBlock.gif            CHAR* tcKeyName = new CHAR[MAX_PATH];
 9InBlock.gif            DWORD dwKeyNameLen = MAX_PATH;
10InBlock.gif            LPBYTE newByte = new BYTE[MAX_PATH];
11InBlock.gif            DWORD nType;
12InBlock.gif            DWORD lpSize=MAX_PATH;
13InBlock.gif            LPBYTE pbbinKeyData=NULL;
14InBlock.gif            while(TRUE)
15ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
16InBlock.gif                //circulate the Register
17InBlock.gif                lResult=RegEnumValue(regOldHKey,dwIndex,tcKeyName,&dwKeyNameLen,NULL,NULL,NULL,NULL);
18InBlock.gif                if(lResult!=ERROR_SUCCESS)
19InBlock.gif                    break//if the End then break;
20InBlock.gif                
21InBlock.gif                //Use the key Get the value
22InBlock.gif                long retValue;
23InBlock.gif                if((retValue=::RegQueryValueEx(regOldHKey,(LPCTSTR)tcKeyName,NULL,&nType,newByte,&lpSize))==ERROR_MORE_DATA)
24ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
25InBlock.gif                    newByte=(LPBYTE)"NULL";
26ExpandedSubBlockEnd.gif                }

27InBlock.gif                
28InBlock.gif                //Print the key and the value
29InBlock.gif                cout<<"Key:"<<(LPCTSTR)tcKeyName;
30InBlock.gif                cout<<"\t";
31InBlock.gif                cout<<"Value:"<<(LPCTSTR)newByte<<endl;
32InBlock.gif                dwIndex++;
33InBlock.gif                dwKeyNameLen=MAX_PATH;
34InBlock.gif                lpSize=MAX_PATH;
35ExpandedSubBlockEnd.gif            }

36ExpandedBlockEnd.gif        }

37 None.gif

 

 

 

第二个问题:Link时出错问题

    在VC中想把注册表删除,查MSDN查到了SHDeleteKey 这个函数,函数使用很简单:

None.gif if (SHDeleteKey(HKEY_CURRENT_USER, " Software\\OKI\\CCons32\\NeedDelete " ) == ERROR_SUCCESS)
ExpandedBlockStart.gifContractedBlock.gif   
dot.gif {
InBlock.gif      cout
<<"Delete Finish"<<endl;
ExpandedBlockEnd.gif   }
   
      MSDN上面注明要加入 shlwapi.h这个头文件,但我另进去之后,link出现错误. 说是LNK2001无法解析的外部符号“symbol”.
不加,找不到函数定义.

   其实解决这个问题很简单.在VC菜单中Project->Setting->Link 下面project options的文本框中,输入shlwapi.lib问题就可以解决了.害得我花了几个小时时间.
   (或者,在Code前面加上#pragma comment(lib,"shlwapi.lib"))也可以解决问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值