To clarify..... I am using GetPrivateProfileString so I have now defined
a
'TCHAR * data_name' and used it asfollows:
GetPrivateProfileString (section_name, field_name, "", data_name, 256,
"C:\ini22.ini");
This works and gives me the correct result! However I am then trying to use
the result in COM by calling a method in an OLE DB provider that requires an
LPOLESTR. I have tried to convert my TCHAR as follows:
_rgColumns[ulCols].pwszName = (LPOLESTR)(T2COLE(data_name)); // and also
T2OLE
But this give me the strange results as sometimes the output is correct and
other times not????
Any further suggestions? I have tried using wchar_t but it did not give
anything meaningful from the GetPrivateProfileString??
First of all, you need to understand all these string types which I can't
fully explain here. Quick summary only: In Windows, all the args you pass to
"GetPrivateProfileString()" and most other WinAPI functions need to be TCHAR
based. Search MSDN for both "Generic Text Mappings" and also see technical
article "TN059" (for starters). In a nutshell, when you compile your app,
all occurrences of TCHAR are changed to "char" if the constants _UNICODE and
UNICODE are *not* #defined or "wchar_t" if they are #defined (the reason for
both #defined constants is another topic). This way, you can create a
Unicode build or an ASCII build simply by #defining these constants or not
at compile time (respectively). So, TCHAR is nothing more than "char" or
"wchar_t" depending on the presence of these #defined constants. Note that
if your app is targetted for WinNT or beyond then you should normally
#define both constants since WinNT works with Unicode under the hood. Your
app will therefore run more efficiently (you can read up on the subject but
the info is widely dispersed).
Now, understand that LPTSTR is simply a pointer to a non-const TCHAR based
string. LPCTSTR (note the added 'C') is a pointer to const TCHAR-based
string. IOW, if the #defined Unicode constants I described above are *not*
present, LPTSTR simply maps to "char *" and LPCTSTR maps to "const char *".
If those Unicode constants *are* #defined however, then LPTSTR maps to
"wchar_t *" and LPCTSTR maps to "const wchar_t *".
All WinAPI functions where you see either LPTSTR or LPCTSTR therefore need
to be passed TCHAR strings only (watch our for some rare functions that take
pure ASCII or Unicode arguments however - these will be LPSTR, LPCSTR,
LPWSTR or LPCWSTR). Most functions work with TCHAR however so you must pass
TCHAR args. String literals for instance should therefore be surrounded
with the _T macro (note that there are other variations on this macro's name
I won't get into here - they all do the same thing). A string like
"C:\\ini22.ini" should therefore be passed as _T("C:\\ini22.ini") instead
(also note the double backslash I added to the string - your original
example doesn't have this but it must - read up on "escape sequences"). The
_T macro simply ensures the string is either ASCII or Unicode accordingly
(by prepending an "L" in front of your string as required - you can read up
on this macro).
Finally, note that all ASCII-based (C-runtime) string functions you would
normally call such as "strcpy()" need to be replaced with their TCHAR
equivalent ("_tcscpy()" in this case). Search by title for "Routine
Mappings" in MSDN.
Now, an LPOLESTR is a different beast. It's actually a string of OLECHARs so
LPOLESTR is simply "OLECHAR *" and LPCOLESTR is a "const OLECHAR *". An
OLECHAR is the character used by COM on the host OS which is simply
"wchar_t" in Win32. So OLECHAR is really a "wchar_t" on all modern versions
of Windows but it should be treated as if it were a real type (OLECHAR, not
"wchar_t"). You can convert from a TCHAR string to an OLECHAR string by
using T2OLE or T2COLE (non-const and const versions). Therefore, your call
should appear as:
_rgColumns[ulCols].pwszName = T2OLE(data_name);
This assumes that "_rgColumns[ulCols].pwszName" is defined as an LPOLESTR,
which presumably it is since you're apparently using it to call an OLE DB
function that takes this (BTW, ADO is typically much easier than using OLE
DB directly). Anyway, the conversion should work correctly assuming you're
following all the rules I've described. If you are and something is still
amiss then something else is causing your problem.
Lastly, note that the "" you're passing as the 3rd arg to
"GetPrivateProfileString()" , which should actually be _T("") as per the
above discussion, may cause an unrelated problem. If an empty string is
returned in "data_name", you can't tell whether your "field_name" is either
missing or simply isn't assigned a value (I'd have to double check and it
may not be an issue for you anway).