Re: Creating and setting registry key value
From: Joseph M. Newcomer (newcomer_at_flounder.com)
Date: 05/26/04
- Next message: Joseph M. Newcomer: "Re: CWnd::GetDlgItem"
- Previous message: jonnyair<>_: "Re: CEdit or CRichEditCtrl text highlighting"
- In reply to: Peter: "Creating and setting registry key value"
- Next in thread: Peter: "Re: Creating and setting registry key value"
- Reply: Peter: "Re: Creating and setting registry key value"
- Messages sorted by: [ date ] [ thread ]
Date: Wed, 26 May 2004 10:51:15 -0400
If you don't create a program with a wizard, you are saying "I LOVE being miserable, and
hitting obscure bugs I don't understand, and generally I LOVE wasting time trying to find
out what I screwed up".
Bottom line: I won't help debug code that is not written by a wizard. I suggest you start
using the tools, and stop playing macho programmer. There is no reason to not use the
tools. And, in spite of the childish myths out there, it is the POOREST way to learn how
to use MFC, because it requires that you concentrate on irrelevant details before you are
ready for them, instead of concentrating on more important issues such as how to use MFC
properly.
But since the numerous errors in this code are unrelated to use or non-use of the wizard,
I'll suggest how to rewrite it so it is correct.
There are significant poor style usages in the code below. For example, why are you
creating a TCHAR of a fixed size, then COPYING a literal string to it, and WHY are you
using "sizeof", which is insane? You could have used a pointer if a literal string were
involved, so why do the copy?
LPCTSTR str = _T("H.prog");
would have made more sense. Copying to fixed-size buffers is poor style, and should only
be done under very restricted conditions, and this is not one of them.
Alternatively, you could have done
#define HPROG _T("H.prog")
and done
RegSetValueEx(hkey, _T(""), 0, REG_SZ, (LPCBYTE)HPROG, lstrlen(HPROG)*sizeof(TCHAR));
and avoided any assignment entirely! But if you need a variable, CString is a better
choice than TCHAR or std::string for this purpose:
CString str(_T("H.prog"));
RegSetValueEx(hkey, _T(""), 0, REG_SZ, (LPCBYTE)(LPCTSTR)str, (DWORD)str.GetLength()*
sizeof(TCHAR));
works well, has the advantage that the second parameter is Unicode-aware (Why you would
use TEXT (a synonym for _T) for one string but not for another escapes me), there is no
need for a fixed-size buffer; why, when the last parameter is specified as DWORD would you
cast it as "unsigned long" escapes me [what makes you think DWORD is "unsigned long"? And
why do you think, if this is correct, that it is the right way to write the code?]? Note
that sizeof() is a compile-time operator that gives you the total size of the buffer in
bytes, and not the length of the string in it. This will cause your program to write more
bytes than are present, including whatever garbage is on the stack. In your second
example, using string, you also neglect to convert from string length to byte length
(Unicode bytes are twice the character count).
joe
On Tue, 25 May 2004 20:38:47 +0100, Peter <peter_denton659@hotmail.com> wrote:
>Hi,
>
>I want to associate my mfc program with an icon yet I am having trouble
>editing the registry to do it. I tried using:
>
>EnableShellOpen();
>RegisterShellFileTypes();
>
>in the InitInstance function but it caused an error. I did not create this
>program with a wizard so the above raises an error for some reason, that's
>why I want to edit the registry directly. The code I have so far does not
>work for Entry 2, I cannot get the full path for the application into the
>registry or any data at all - I would also like to get the executable's
>name but I do not know how to get it.
>
>Entry 1's code is ok and I have included it for completeness. Is this code
>correct for setting icon information in the registry?
>
>I have placed this code in my main frame's OnCreate event.
>
>//Entry 1
>//HKEY_CLASSES_ROOT\.my
>//(standard) "myfile"
>
>//set up file types manually
>HKEY hKey;
>RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT(".xyz"), 0,
> NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
> NULL, &hKey, NULL);
>
>TCHAR lpStr[100];
>lstrcpy(lpStr, TEXT("H.Prog"));
>RegSetValueEx(hKey, "", 0, REG_SZ,
> (unsigned char *) lpStr, (unsigned long) sizeof(lpStr));
>
>RegCloseKey(hKey);
>
>//Entry 2
>//HKEY_CLASSES_ROOT\myfile
>//HKEY_CLASSES_ROOT\myfile\DefaultIcon
>//(standard) "c:\path\app.exe,<index>"
>
>HKEY hKey2;
>RegCreateKeyEx(HKEY_CLASSES_ROOT, TEXT("H.Prog\\DefaultIcon"), 0,
> NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
> NULL, &hKey2, NULL);
>
>string pathstr = AppPath(); //how do you get the name of the exe too?
****
TCHAR path[MAX_PATH]; // one of the few places you would allocate a fixed buffer
GetModuleFileName(NULL, path, MAX_PATH); // not sure about parameter order, check
CString pathstr = path;
****
>pathstr += ",";
****
_T(",")
****
>pathstr += "1";
****
_T("1")
****
>int bytecount = lstrlen(pathstr.c_str());
****
you forgot "*sizeof(TCHAR)" in the computation of the byte count. If you use CString, and
TEXT or _T, you need to account for Unicode issues everywhere. I don't know if 'string' is
Unicode-aware or not, but if it isn't, it would be an exceedingly poor choice of type. If
it is, you need to account for the byte conversion.
Also, why did you use std::string here and a fixed buffer in the other case, and why not
use CString? It would have been easier; you don't need the c_str() operator at all, you
could have written
(LPCBYTE)(LPCTSTR)pathstr
for the pointer to the string.
****
>
>//not working, no data in reg
>long code = RegSetValueEx(hKey2, "", 0, REG_SZ,
> reinterpret_cast<const unsigned char*>(pathstr.c_str()), bytecount);
*****
Why something long and clumsy like
reinterpret_cast<const unsigned char *>
when it would make more sense to write
reinterpret_cast(LPCBYTE)
or the even shorter
(LPCBYTE)
do you have religious opposition to using the Windows types, or do you just like to write
error-prone code? Those types are defined for a reason, and it is poor style to ignore
them.
****
>
>RegCloseKey(hKey2);
>
>ASSERT(code == ERROR_SUCCESS);
>
>
>Thanks.
>Peter.
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
- Next message: Joseph M. Newcomer: "Re: CWnd::GetDlgItem"
- Previous message: jonnyair<>_: "Re: CEdit or CRichEditCtrl text highlighting"
- In reply to: Peter: "Creating and setting registry key value"
- Next in thread: Peter: "Re: Creating and setting registry key value"
- Reply: Peter: "Re: Creating and setting registry key value"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|