In the process of using VC, we will encounter many small and complex problems, many of which are due to the complexity of C ++ language, API, and the complexity of the MFC class library, and the types of function parameters are inconsistent, and other external functions such as macro, C, and C ++ are shared, Program Compile, link, and so on.
Two problems encountered today: one is incorrect in the function parameter type and the other is an error in the link to Lib.
I. First, I want to traverse the Registry. I can use the regenumvalue API function to traverse the Registry. However, some of them can be traversed, but some cannot be traversed. Check the program:
This is my first program:
1 Hkey regoldhkey;
2
3 // Open register key
4 If (: Regopenkeyex (HKEY_CURRENT_USER, " Software \ Oki \ ccons33 \ unittype " , 0 , Key_all_access, & Regoldhkey) = Error_success)
5 {
6 Long Lresult;
7 DWORD dwindex;
8 Char * Tckeyname = New Char [max_path];
9 DWORD dwkeynamelen = Max_path;
10 DWORD lpsize, ntype;
11 Lpbyte newbyte = New Byte [max_path]
12 While (True)
13 {
14 // Circulate the Register
15 Lresult = Regenumvalue (regoldhkey, dwindex, tckeyname, & Dwkeynamelen, null );
16 If (Lresult ! = Error_success)
17 Break ; // If the end then break;
18
19 // Use the key get the value
20 If (: Regqueryvalueex (regoldhkey, (lpctstr) tckeyname, null, & Ntype, newbyte, & Lpsize) = Error_more_data)
21 {
22Newbyte=(Lpbyte)"Null";
23}
24
25 // Print the key and the Value
26 Cout < " Key: " < (Lpctstr) tckeyname;
27 Cout < " \ T " ;
28 Cout < " Value: " < (Lpctstr) newbyte;
29 }
30 }
This program has several problems and cannot be traversed at all!
First, let's look at the regenumvalue function prototype:
Long regenumvalue (
Hkey,
DWORD dwindex,
Lptstr lpvaluename,
Lpdword lpcvaluename,
Lpdword lpreserved,
Lpdword lptype,
Lpbyte lpdata,
Lpdword lpcbdata
);
As mentioned above in msdn, dwindex must be initialized before it is used. dwindex plays a counter role in the traversal process. If the program is not initialized, a warning will appear during compilation.
Therefore, the seventh line should initialize dwindex: DWORD dwindex = 0;
Second, it was discovered only when I encountered a problem. When a parameter involves pointers, but the real parameter itself is not a pointer type, we need to add the & address character before the parameter, as shown in the preceding figure.Dwkeynamelen, Ntype, lpsize, etc. The API will change it. Generally, it is okay to call it once, but here it is a loop, and the value written last time may affect the next execution.
For example, dwkeynamelen is used as a string buffer. The first execution is acceptable. After the first execution, its value is the length of the lpdata string. The second time is also acceptable, because the length of the second lpdata traversal is smaller than the first time, but the length of the third lpdata string is longer than the first time. In this case, regenumvalue returns an error_more_data return value and jumps out of the loop. (That is, the length of the buffer cannot meet the lpdata string ).
The problem related to this is also the same with lpsize. When the length indicated by lpsize in the regqueryvalueex function is insufficient, the function will reject writing newbyte and return error_more_data.
So, for the above problem, we need to initialize the values of dwkeynamelen and newbyte before the next traversal.
Dwkeynamelen = max_path;
Newbyte = max_path;
The last problem is that dwindex is used as the counter and does not perform the auto-increment operation at the end, which will lead to an endless loop.
CorrectCodeAs follows:
1 Hkey regoldhkey;
2
3 // Open register key
4 If (: Regopenkeyex (HKEY_CURRENT_USER, " Software \ Oki \ ccons33 \ unittype " , 0 , Key_all_access, & Regoldhkey) = Error_success)
5 {
6 Long Lresult;
7 DWORD dwindex = 0 ;
8 Char * Tckeyname = New Char [max_path];
9 DWORD dwkeynamelen = Max_path;
10 Lpbyte newbyte = New Byte [max_path];
11 DWORD ntype;
12 DWORD lpsize = Max_path;
13 Lpbyte pbbinkeydata = NULL;
14 While (True)
15 {
16 // Circulate the Register
17 Lresult = Regenumvalue (regoldhkey, dwindex, tckeyname, & Dwkeynamelen, null );
18 If (Lresult ! = Error_success)
19 Break ; // If the end then break;
20
21 // Use the key get the value
22 Long Retvalue;
23 If (Retvalue = : Regqueryvalueex (regoldhkey, (lpctstr) tckeyname, null, & Ntype, newbyte, & Lpsize )) = Error_more_data)
24 {
25Newbyte=(Lpbyte)"Null";
26}
27
28 // Print the key and the Value
29 Cout < " Key: " < (Lpctstr) tckeyname;
30 Cout < " \ T " ;
31 Cout < " Value: " < (Lpctstr) newbyte < Endl;
32 Dwindex ++ ;
33 Dwkeynamelen = Max_path;
34 Lpsize = Max_path;
35 }
36 }
37
Second problem: Link error
To delete the Registry in VC, check the shdeletekey function in msdn. The function is easy to use:
If (Shdeletekey (HKEY_CURRENT_USER, " Software \ Oki \ ccons32 \ needdelete " ) = Error_success)
{
Cout<"Delete finish"<Endl;
}
The msdn above indicates to addThe header file shlwapi. h, but after I entered the header file, the link encountered an error, saying that it was an external symbol "symbol" That lnk2001 could not parse ".
No function definition is found.
In fact, it is very easy to solve this problem. in the project options text box under project> setting> link in the VC menu, enter shlwapi. the LIB problem can be solved. it took me a few hours.
(Or, add # pragma comment (Lib, "shlwapi. lib") before the code to solve the problem.