Reputation: 2409
I think I am going about this wrong. I'm working on making a SO for a MSR type object. And by default (if I read it correctly) OPOS uses unicode. So I made my C++ automated class use unicode as well and from what I understand there is no way around it. In the OPOS head class there are 2 string definitions, the third one is one my creation:
#define OPOS_ROOTKEY "SOFTWARE\\OLEforRetail\\ServiceOPOS"
#define OPOS_CLASSKEY_MSR "MSR"
#define OPOSMSR OPOS_ROOTKEY "\\" OPOS_CLASSKEY_MSR "\\"
This is so that a person can access the registry. So I decided to make myself a registry helper class instead of having it all in my SO. Looks like I'm having a hard time trying to figure out how I should do this in the end. I copied working code from another SO I had, but I feel that that code was not made correctly, and I want my code made right the first time.
So I came up with this, but I can not figure out how to combine my string with the class name. I made the class name as a parameter in my constructor.
RegistryHelper::RegistryHelper(LPCTSTR deviceName) {
cout << "RegistryHelper::RegistryHelper()+" << endl;
baseOpen = true;
CString test;
test.Format("%s%s",OPOSMSR, theClass); //fail
REGSAM access = KEY_READ | KEY_WOW64_64KEY;
LONG nError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, theClass ,0, access,&hBaseKey); //not what I want, but would compile, I want test here instead of theClass
if (nError != ERROR_SUCCESS) {
cerr << "(E)RegistryHelper::RegistryHelper(): Failed to load base key. [" <<(int)nError << "]" << endl;
RegCloseKey(hBaseKey);
baseOpen = false;
}
cout << "RegistryHelper::RegistryHelper()-" << endl;
}
Any tips on what I am doing wrong? since I'm on the subject: I'm going to post all my code for this. How bad is it?
What I'm after is something like this
unsigned int baud;
char* parity;
bool MSRSO::LoadRegistryValuesIntoMemory(LPCSTR deviceName) {
RegistryHelper reg(deviceName);
bool required = reg.LoadDWORD("BaudRate", 19200, baud);
required = required && reg.LoadREGSZ("Parity", "NONE", parity);
//other values
reg.Close();
return required;
}
Keep in mind I'm a C# and java guy so I may have my data types wrong. I only wrote simple hello world programs and temp conversion programs for myself in C++ on a SUPER old linux box back in the day. Although I am getting better at C++ I'm still not comfortable with it. So to sum up what is the data type of the #define type? How do I combine it with LPCTSTR? Should I have done that so that I can access registry values ONLY?
Thank you.
Upvotes: 1
Views: 2231
Reputation: 61900
Your code has inconsistencies between narrow and wide strings. A literal 'a'
has the type char
, and is a narrow character. A literal L'a'
has the type wchar_t
, and is a wide character.
Next, we can apply these to strings:
"abc"
is a narrow string of type const char (&)[4]
.
L"abc"
is a wide string of type const wchar_t (&)[4]
.
To reduce the hassle of supporting both, there is what is known as the TCHAR
. Defined in a Windows header, this type is char
or wchar_t
, depending on whether UNICODE
is defined. If it is defined, TCHAR
will be wchar_t
. If it is not defined, TCHAR
will be char
.
This also came with a TEXT
macro that converts a string literal into characters of type TCHAR
. That is, if UNICODE
is defined, TEXT("abc")
will be equivalent to L"abc"
, and if it is not defined, TEXT("abc")
will be equivalent to "abc"
.
Strings were also given some typedefs as well:
LP[C][W|T]STR
The LP
indicates a pointer, and the STR
indicates "to a string". If C
is included, the string will be a constant one. If W
or T
is included, the string will be made of characters of type wchar_t
or TCHAR
respectively.
For example:
LPSTR: char *
LPCSTR: const char *
LPWSTR: wchar_t *
LPCTSTR: const TCHAR *
Using this information, you can correctly understand why using TCHAR
and TEXT
will cause your code to become compatible with something else, whether it uses narrow or wide characters.
Here's a simple example, keeping in mind that std::string
is, for our purposes, std::basic_string<char>
:
std::basic_string<TCHAR> s(TEXT("abcd"));
s += TEXT("ZYXW"); //s is now `TEXT("abcdZXW")
Upvotes: 3
Reputation: 2558
Change
#define OPOS_ROOTKEY "SOFTWARE\\OLEforRetail\\ServiceOPOS" #define OPOS_CLASSKEY_MSR "MSR" #define OPOSMSR OPOS_ROOTKEY "\\" OPOS_CLASSKEY_MSR "\\"
to
#define OPOS_ROOTKEY L"SOFTWARE\\OLEforRetail\\ServiceOPOS" #define OPOS_CLASSKEY_MSR L"MSR" #define OPOSMSR OPOS_ROOTKEY L"\\" OPOS_CLASSKEY_MSR "\\"
Upvotes: 1