Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Difference between L"" and _T("")

Posted on 2009-02-12
13
Medium Priority
?
2,184 Views
Last Modified: 2012-05-06
Hello
If i use _T("") in .h file, code is getting compiled successfully.this is non-unicde project.
If i use L"" in place of _T("") in .h file, i get the following error, Please find the attached code snippet.
I mentioned the line # 3849 in .c file, count accordingly. Weherever the macros are being used, i see the error.

Can u please answer the reason?


\TNGWVSSAPI.C(3859) : error C2220: warning treated as error - no object file generated
TNGWVSSAPI.C(3859) : warning C4133: 'function' : incompatible types - from 'unsigned short [36]' to 'LPCSTR'
\TNGWVSSAPI.C(3864) : warning C4133: 'function' : incompatible types - from 'unsigned short [36]' to 'LPCSTR'
TNGWVSSAPI.C(3908) : warning C4133: 'function' : incompatible types - from 'unsigned short [12]' to 'LPCSTR'
TNGWVSSAPI.C(3914) : warning C4133: 'function' : incompatible types - from 'unsigned short [10]' to 'const unsigned char *'
TNGWVSSAPI.C(3920) : warning C4133: 'function' : incompatible types - from 'unsigned short [11]' to 'LPCSTR'
TNGWVSSAPI.C(3935) : warning C4133: 'function' : incompatible types - from 'unsigned short [6]' to 'LPCSTR'
TNGWVSSAPI.C(3955) : warning C4133: 'function' : incompatible types - from 'unsigned short [6]' to 'LPCSTR'
NMAKE : fatal error U1077: 'cl' : return code '0x2'
Stop.


////////////////////////////.h file//////////////////////////////
#define MSI_SOURCE_BASE_KEY			L"SOFTWARE\\Classes\\Installer\\Products"
#define WVSevProp_MSI		L"WVSevProp"
#define MSI_SOURCE_KEY		L"SourceList"
#define MSI_MEDIA_KEY		L"Media"
#define MSI_PRODUCT_NAME_KEY	L"ProductName"
//////////////////////////////////.h file/////////////////////////////////////////////
 
 
 
///////////////////////////////////////////////////.c file ///////////////////////////////
void set_mediapkgpath() //Line #3849
{
       HKEY   hkey;
       LONG   ccode;
       REGSAM  samRedirect = 0;
	   
 
		TRACEENTER;
 
    // Open the installer products key.
       if ((ccode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, MSI_SOURCE_BASE_KEY, 0, samRedirect | KEY_ALL_ACCESS, &hkey)) != ERROR_SUCCESS)
       {
		   TRACEF(FW_TRCARGS, "Unable to open MSI Installer Product base key in 32-bit registry ");
		   
			samRedirect |= KEY_WOW64_64KEY;
			if ((ccode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, MSI_SOURCE_BASE_KEY, 0, samRedirect | KEY_ALL_ACCESS, &hkey)) != ERROR_SUCCESS)
			{
			   TRACEF(FW_TRCARGS, "Unable to open MSI Installer Product base key in 64-bit registry");
               
			}  
			else
			{
                  TRACEF(FW_TRCARGS, " Opened MSI Installer Product base key in 64-bit registry.");
				  
			}
		}
		else
		{
              TRACEF(FW_TRCARGS, " Opened MSI Installer Product base key in 32-bit registry.");
			  
		}
 
		// Enumerate the key to find our product's key.
		if( ccode == ERROR_SUCCESS )
		{
			TCHAR      enumname[256];
              DWORD         enumnamelen = sizeof( enumname );
              DWORD         index =0L;
              FILETIME      dummy;
 
              ccode = ERROR_SUCCESS;
              while (ccode == ERROR_SUCCESS)
              {
                     HKEY   hsubkey;
					 TCHAR  prodname[256];
					 DWORD  prodnamelen = sizeof( prodname );
 
                     enumnamelen = sizeof( enumname );
                     ccode = RegEnumKeyEx(hkey, index, enumname, &enumnamelen, NULL, NULL, NULL,  &dummy);
                     if (ccode != ERROR_SUCCESS)
                           break;
                     TRACEF(FW_TRCARGS, " Found subkey Checking...");
					 
                     if ((ccode = RegOpenKeyEx(hkey, enumname, 0, samRedirect | KEY_ALL_ACCESS, &hsubkey) != ERROR_SUCCESS))
                     {
                           TRACEF(FW_TRCARGS, "Unable to open MSI Installer Product sub key ");
						   
                     }
                     else
                     if ((ccode = RegQueryValueEx(hsubkey, MSI_PRODUCT_NAME_KEY, NULL, NULL, (LPBYTE) prodname, &prodnamelen)) != ERROR_SUCCESS)
                     {
                           TRACEF(FW_TRCARGS, " Unable to query for ProductName");
						   
                     }
                     else
                     if (!_tcsicmp(prodname, WVSevProp_MSI))
                     {
                           HKEY   hkeysrclist;
 
                           TRACEF(FW_TRCARGS, " Found WVSevProp  key!");
					
						   if ((ccode = RegOpenKeyEx(hsubkey, MSI_SOURCE_KEY, 0, samRedirect | KEY_ALL_ACCESS, &hkeysrclist) != ERROR_SUCCESS))
                           {//unable to open sourcelist key
                                  TRACEF(FW_TRCARGS, " Unable to open MSI Installer SourceList key ");
								  
                           }
                           else
                           {//source list key opened
							   TCHAR       mediapackage[1040];
								DWORD  mediapackagelen = sizeof( mediapackage );
								HKEY hkeymedia;
								
								
								wchar_t  msiLocation[] = L"\\CCS\\VOL2\\NT\\WVFILES\\SevProp";
								LPCWSTR  msi_media_package_val	=	L"MediaPackage";
																
								if ((ccode = RegOpenKeyEx(hkeysrclist, MSI_MEDIA_KEY, 0, samRedirect | KEY_ALL_ACCESS, &hkeymedia) == ERROR_SUCCESS))
								{ // media key found
									
									TRACEF(FW_TRCARGS, "  Successfully open Media key");
								   
									//Without checking the existence of MediaPackage path string, set MediaPackage to L"\\CCS\\VOL2\\NT\\WVFILES\\SevProp"								  
									if ((ccode = RegSetValueExW( hkeymedia, msi_media_package_val, 0, REG_SZ,(LPBYTE)msiLocation,(DWORD)wcslen(msiLocation)*sizeof(wchar_t) ))  != ERROR_SUCCESS)
 
									{
											// Failed to set it.
											TRACEF(FW_TRCARGS, " Unable to set MediaPackage value ");
									}
									RegCloseKey(hkeymedia);
                                  
                                RegCloseKey(hkeysrclist);
								}
								else
								{// media key not found, create one.
									//Create the media key.
									DWORD dwDisp;
									if ((ccode =RegCreateKeyEx(hkeysrclist, MSI_MEDIA_KEY,0, NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL, &hkeymedia, &dwDisp))!= ERROR_SUCCESS) 
									{
										TRACEF(FW_TRCARGS, "unable to create media key");
 
									}
									else
									{//able to create media key
										if( ( ccode = RegSetValueExW( hkeymedia, msi_media_package_val, 0, REG_SZ,(LPBYTE)msiLocation,(DWORD)wcslen(msiLocation)*sizeof(wchar_t)) ) != ERROR_SUCCESS)
										{
											// Failed to set it.
											TRACEF(FW_TRCARGS, " Unable to set MediaPackage value after creating media key ");
										}
										
									}
 
 
 
								}
						   
						   
						   }
						   break;
                     }
					else
					{
                           TRACEF(FW_TRCARGS, " Haven't yet found WVSevProp product key...");
						   
					}
                     index++;
                     RegCloseKey(hsubkey);
              }
              if (ccode != ERROR_NO_MORE_ITEMS && ccode != ERROR_SUCCESS)
              {
				  // not find wvsevprop
					TRACEF(FW_TRCARGS,"wvsevprop not found");
              }
              RegCloseKey(hkey);
       }
       
		TRACEEXITB(TRUE);		
		return;
}
///////////////////////////////////.c file //////////////////////////////////////////

Open in new window

0
Comment
Question by:sham_ibmgs
  • 3
  • 3
  • 2
  • +2
12 Comments
 
LVL 17

Accepted Solution

by:
rstaveley earned 200 total points
ID: 23631261
_T("") is equivalent to "" in a non-UNICODE project and L"" in a UNICODE project.
0
 
LVL 29

Expert Comment

by:pepr
ID: 23631395
_T is the macro that is expanded to L if the project says UNICODE. The same macro is expanded to nothing if the project does not define the UNICODE. Using _T() or TEXT() macros, you write the sources that can be compiled or as Unicode or as non-Unicode applications.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 23631750
To add to above information:

The so-called T-switch is an attempt of Microsoft to let you develop an application which can be turned from ANSI strings to UNICODE strings and reverse by simply set or reset one preprocessor macro. The base for ANSI is char type while for UNICODE it is wchar_t type. There are three flaws with that approach: (1) it only works if you consequently use the T-types TCHAR, LPTSTR, LPCTSTR, and more and the _T macro for literals in your program. If using L"text" in a non-unicode project like you did above, you can't pass that to a T-variable without conversion. Or even if it works cause you used the currently defined char or wchar_t, it would fail after you switch back to the other char type. (2) If using the T-type you badly can handle both string types. If for example you read a file where you know that it is ANSI-Text you can't take the CStdioFile::ReadString if you have a UNICODE project cause it only reads wide texts. (3) Most other libraries, even STL, don't support the T-switch. So, at least if you use some of these you always have to know what the current switch is and have to add explicit conversions from wchar_t to char and reverse.

For example you always could do:

   if (sizeof(TCHAR) == sizeof(char))   // ANSI
   {
         string  s = (const char*)someTString;
   }
   else
   {
         wstring  w = (const wchar_t*)someTString;
    }  

but I rarely have seen such ugly code and I never would recommend to do so. You better decide for one of these choices and change the T types either to CHAR, LPSTR, ... in case of ANSI or to WCHAR, LPWSTR, ... in UNICODE.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 29

Expert Comment

by:pepr
ID: 23632060
For the conversions related to T-switch mentioned by itsmeandnobodyelse, you may find convenient to use ATL and its macros/classes like CA2T() -- from const char * to TCHAR * -- and the other with the name derived what is converted to what. See http://msdn.microsoft.com/en-us/library/87zae4a3(VS.80).aspx
0
 

Author Comment

by:sham_ibmgs
ID: 23641707
Hello itmeans

In the above code i do not have liberty to make it unicode project, so i will make below  macros as ""(char) strings, hope this works:
#define MSI_SOURCE_BASE_KEY                  L"SOFTWARE\\Classes\\Installer\\Products"
#define WVSevProp_MSI            L"WVSevProp"
#define MSI_SOURCE_KEY            L"SourceList"
#define MSI_MEDIA_KEY            L"Media"
#define MSI_PRODUCT_NAME_KEY      L"ProductName"



But in the below 3 lines i need 5th argument to be wide character based on the app and i have liberty to change 2nd argument to any char type. Please let me know the changes that i can do for the below lines:

1)wchar_t  msiLocation[] = L"\\CCS\\VOL2\\NT\\WVFILES\\SevProp";
2)LPCWSTR  msi_media_package_val      =      L"MediaPackage";
3)if ((ccode = RegSetValueExW( hkeymedia, msi_media_package_val, 0, REG_SZ,(LPBYTE)msiLocation,(DWORD)wcslen(msiLocation)*sizeof(wchar_t) ))  

Regards
Sham
0
 

Author Comment

by:sham_ibmgs
ID: 23641711
Hello

Is it wise to include wchar_t declarations for handling wide characters in a project, despite the project being non-unicode?

Regards
Sham
0
 

Author Comment

by:sham_ibmgs
ID: 23647424
Hello

Can i get  update for my 2 latest updates?

Regards
Sham
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 23647445
>>>> Is it wise to include wchar_t declarations for handling wide characters in a project

Yes, of course. You only should omit the TCHAR and its derivates.


>>>> Please let me know the changes that i can do for the below lines:
Looks ok for me. Any problems?
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 23648285
I'm rusty when it comes to Win32 programming, but this looks iffy:

> 3)if ((ccode = RegSetValueExW( hkeymedia, msi_media_package_val, 0, REG_SZ,(LPBYTE)msiLocation,(DWORD)wcslen(msiLocation)*sizeof(wchar_t) ))  

Make the length include the L'\0' terminator, and you'll make it easier for the getter.

i.e.

((DWORD)wcslen(msiLocation)+1)*sizeof(wchar_t)
0
 
LVL 8

Expert Comment

by:milindsm
ID: 25402116
_T("") will take care of your string based on the UNICODE or non-UNICODE project... so just use _T("") and enjoy the show
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 25404203
>>>> so just use _T("") and enjoy the show
As told above, there is nothing to enjoy if you were using libraries or portable code that don't have the T-switch applied as well. IMO, MS implemented the T-switch to prevent developers from developing/using portable code. E. g. STL strings cannot be used with reasonable effort if you really would like to switch from UNICODE to ANSI and back.

0
 
LVL 8

Expert Comment

by:milindsm
ID: 25404561
II agree... I should have been a bit precised...!!!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question