We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

Difference between L"" and _T("")

sham_ibmgs
sham_ibmgs asked
on
Medium Priority
3,010 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

Comment
Watch Question

_T("") is equivalent to "" in a non-UNICODE project and L"" in a UNICODE project.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
CERTIFIED EXPERT

Commented:
_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.
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.
CERTIFIED EXPERT

Commented:
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

Author

Commented:
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

Author

Commented:
Hello

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

Regards
Sham

Author

Commented:
Hello

Can i get  update for my 2 latest updates?

Regards
Sham
>>>> 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?
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)

Commented:
_T("") will take care of your string based on the UNICODE or non-UNICODE project... so just use _T("") and enjoy the show
>>>> 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.

Commented:
II agree... I should have been a bit precised...!!!
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.