Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. Getting AppData Directory Path

Getting AppData Directory Path

Scheduled Pinned Locked Moved ATL / WTL / STL
helpquestion
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jwalker343
    wrote on last edited by
    #1

    Ok guys... i've been working on this section of code for about a week now and i'm giving up...can someone help me? I've got the basics down, but the code won't compile: Argument of type LPWSTR* is incompatible with parameter type of LPWSTR

    //read in hotkey settings

    // String buffer for holding the path.
    LPWSTR strPath\[ MAX\_PATH \];
    
    // Get the special folder path.
    SHGetSpecialFolderPath(
    	0,       // Hwnd
    	strPath, // String buffer.
    	CSIDL\_APPDATA, // CSLID of folder
    	FALSE ); // Create if doesn't exists?
    
    
    LPWSTR appDataPath = \*strPath;
    \_tcscat(appDataPath, L"\\\\SSST\\Settings.ini");
    
    MessageBox(NULL,(LPCTSTR)appDataPath, NULL, NULL);
    
    Richard Andrew x64R M 2 Replies Last reply
    0
    • J jwalker343

      Ok guys... i've been working on this section of code for about a week now and i'm giving up...can someone help me? I've got the basics down, but the code won't compile: Argument of type LPWSTR* is incompatible with parameter type of LPWSTR

      //read in hotkey settings

      // String buffer for holding the path.
      LPWSTR strPath\[ MAX\_PATH \];
      
      // Get the special folder path.
      SHGetSpecialFolderPath(
      	0,       // Hwnd
      	strPath, // String buffer.
      	CSIDL\_APPDATA, // CSLID of folder
      	FALSE ); // Create if doesn't exists?
      
      
      LPWSTR appDataPath = \*strPath;
      \_tcscat(appDataPath, L"\\\\SSST\\Settings.ini");
      
      MessageBox(NULL,(LPCTSTR)appDataPath, NULL, NULL);
      
      Richard Andrew x64R Offline
      Richard Andrew x64R Offline
      Richard Andrew x64
      wrote on last edited by
      #2

      The problem with your code is as follows:

      LPWSTR strPath[ MAX_PATH ];

      The "LP" in "LPWSTR" stands for Long Pointer. So the above code declares an array of pointers, NOT an array of WCHARs. You need to declare it as:

      WCHAR strPath[ MAX_PATH ];

      Also, this code is wrong:

      LPWSTR appDataPath = *strPath;
      _tcscat(appDataPath, L"\\SSST\Settings.ini");

      You haven't allocated any memory for the appDataPath string. So you must make it something like:

      LPWSTR appDataPath = new WCHAR[ 400 ];

      I chose 400 arbitrarily to make it big enough. And be sure to deallocate appDataPath when you are done with it by saying:

      delete [] appDataPath;

      The difficult we do right away... ...the impossible takes slightly longer.

      J 1 Reply Last reply
      0
      • Richard Andrew x64R Richard Andrew x64

        The problem with your code is as follows:

        LPWSTR strPath[ MAX_PATH ];

        The "LP" in "LPWSTR" stands for Long Pointer. So the above code declares an array of pointers, NOT an array of WCHARs. You need to declare it as:

        WCHAR strPath[ MAX_PATH ];

        Also, this code is wrong:

        LPWSTR appDataPath = *strPath;
        _tcscat(appDataPath, L"\\SSST\Settings.ini");

        You haven't allocated any memory for the appDataPath string. So you must make it something like:

        LPWSTR appDataPath = new WCHAR[ 400 ];

        I chose 400 arbitrarily to make it big enough. And be sure to deallocate appDataPath when you are done with it by saying:

        delete [] appDataPath;

        The difficult we do right away... ...the impossible takes slightly longer.

        J Offline
        J Offline
        jwalker343
        wrote on last edited by
        #3

        Great! that works perfect, the only issue is that now the MessageboxA shows a ton of chinese/gibberish characters at the front.. i'm assuming that these are the buffer characters? i'm new to C++ (in fact this is only my second attempt at C++)... counting "Hello World!"

        Richard Andrew x64R 1 Reply Last reply
        0
        • J jwalker343

          Great! that works perfect, the only issue is that now the MessageboxA shows a ton of chinese/gibberish characters at the front.. i'm assuming that these are the buffer characters? i'm new to C++ (in fact this is only my second attempt at C++)... counting "Hello World!"

          Richard Andrew x64R Offline
          Richard Andrew x64R Offline
          Richard Andrew x64
          wrote on last edited by
          #4

          I should have mentioned that you should zero out the buffer before using it:

          LPWSTR appDataPath = new WCHAR[ 400 ];
          ZeroMemory( appDataPath, sizeof( WCHAR ) * 400 );

          The difficult we do right away... ...the impossible takes slightly longer.

          1 Reply Last reply
          0
          • J jwalker343

            Ok guys... i've been working on this section of code for about a week now and i'm giving up...can someone help me? I've got the basics down, but the code won't compile: Argument of type LPWSTR* is incompatible with parameter type of LPWSTR

            //read in hotkey settings

            // String buffer for holding the path.
            LPWSTR strPath\[ MAX\_PATH \];
            
            // Get the special folder path.
            SHGetSpecialFolderPath(
            	0,       // Hwnd
            	strPath, // String buffer.
            	CSIDL\_APPDATA, // CSLID of folder
            	FALSE ); // Create if doesn't exists?
            
            
            LPWSTR appDataPath = \*strPath;
            \_tcscat(appDataPath, L"\\\\SSST\\Settings.ini");
            
            MessageBox(NULL,(LPCTSTR)appDataPath, NULL, NULL);
            
            M Offline
            M Offline
            MicroVirus
            wrote on last edited by
            #5

            Though what the other poster said is correct, you need to make a few extra modifications. First I'll give you the working 'proper' code, and then I'll explain:

                // String buffer for holding the path and filename
                TCHAR strPath\[ MAX\_PATH + 50 \];
            
            // Get the special folder path.
            SHGetSpecialFolderPath(
            	0,       // Hwnd
            	strPath, // String buffer.
            	CSIDL\_APPDATA, // CSLID of folder
            	FALSE ); // Create if doesn't exists?
            
            \_tcscat(strPath, \_T("\\\\SSST\\\\Settings.ini"));
            
            MessageBox(NULL, strPath, NULL, MB\_OK);
            

            First of all, you were mixing WCHAR definitions with TCHAR functions (such as _tcscat, MessageBox). Depending on whether you compile for Unicode or not, the TCHAR definition changed from a char to a wchar_t, and so do all the tchar.h routines, as well as the Windows API functions (which switch to their wide variants). To fix this, use TCHAR and LPTSTR's in your program. For string literals, enclose them in a _T macro as shown, which automatically adds the L prefix if needed and omits it if not unicode. Then a simplification: you can just strcat (_tcscat) in strPath, no need to add extra variables and certainly no need to use new, which adds the overhead of extra memory management and can lead to memory leaks if you forget to clean it up. And finally, the last argument of the MessageBox is a UINT flag, and not a pointer, so you shouldn't pass NULL to it, but rather one of the predefined constants. Hope this helps.

            J 1 Reply Last reply
            0
            • M MicroVirus

              Though what the other poster said is correct, you need to make a few extra modifications. First I'll give you the working 'proper' code, and then I'll explain:

                  // String buffer for holding the path and filename
                  TCHAR strPath\[ MAX\_PATH + 50 \];
              
              // Get the special folder path.
              SHGetSpecialFolderPath(
              	0,       // Hwnd
              	strPath, // String buffer.
              	CSIDL\_APPDATA, // CSLID of folder
              	FALSE ); // Create if doesn't exists?
              
              \_tcscat(strPath, \_T("\\\\SSST\\\\Settings.ini"));
              
              MessageBox(NULL, strPath, NULL, MB\_OK);
              

              First of all, you were mixing WCHAR definitions with TCHAR functions (such as _tcscat, MessageBox). Depending on whether you compile for Unicode or not, the TCHAR definition changed from a char to a wchar_t, and so do all the tchar.h routines, as well as the Windows API functions (which switch to their wide variants). To fix this, use TCHAR and LPTSTR's in your program. For string literals, enclose them in a _T macro as shown, which automatically adds the L prefix if needed and omits it if not unicode. Then a simplification: you can just strcat (_tcscat) in strPath, no need to add extra variables and certainly no need to use new, which adds the overhead of extra memory management and can lead to memory leaks if you forget to clean it up. And finally, the last argument of the MessageBox is a UINT flag, and not a pointer, so you shouldn't pass NULL to it, but rather one of the predefined constants. Hope this helps.

              J Offline
              J Offline
              jwalker343
              wrote on last edited by
              #6

              it did help significantly, i appreciate the explanation rather than a code dump... I'm still a bit confused about the TCHAR and WCHAR definitions... they seem to convert themselves... i guess these are one of those "C++ Macros" that i've been reading about? i figured i could just strcat() the strings in the same line, but i'm still trying to figure out C++ i've made the changes stated above, but i am now getting a "Debug Assertion Error" on my line:

              delete [] strPath

              i've figured out that an assertion error is similar to a conditioned break point... i've found the line of code in one of the C++ files: dbgdel.cpp

              void operator delete(
              void *pUserData
              )
              {
              _CrtMemBlockHeader * pHead;

                  RTCCALLBACK(\_RTC\_Free\_hook, (pUserData, 0));
              
                  if (pUserData == NULL)
                      return;
              
                  \_mlock(\_HEAP\_LOCK);  /\* block other threads \*/
                  \_\_TRY
              
                      /\* get a pointer to memory block header \*/
                      pHead = pHdr(pUserData);
              
                       /\* verify block type \*/
                      \_ASSERTE(\_BLOCK\_TYPE\_IS\_VALID(pHead->nBlockUse));
              
                      \_free\_dbg( pUserData, pHead->nBlockUse );
              
                  \_\_FINALLY
                      \_munlock(\_HEAP\_LOCK);  /\* release other threads \*/
                  \_\_END\_TRY\_FINALLY
              
                  return;
              

              }

              #endif /* _DEBUG */

              the code looks like i've passed an invalid param to the delete function... should i not be disposing of this variable, it is not used anywhere else in my code as of yet? or is there another method for disposing of this var?

              M 1 Reply Last reply
              0
              • J jwalker343

                it did help significantly, i appreciate the explanation rather than a code dump... I'm still a bit confused about the TCHAR and WCHAR definitions... they seem to convert themselves... i guess these are one of those "C++ Macros" that i've been reading about? i figured i could just strcat() the strings in the same line, but i'm still trying to figure out C++ i've made the changes stated above, but i am now getting a "Debug Assertion Error" on my line:

                delete [] strPath

                i've figured out that an assertion error is similar to a conditioned break point... i've found the line of code in one of the C++ files: dbgdel.cpp

                void operator delete(
                void *pUserData
                )
                {
                _CrtMemBlockHeader * pHead;

                    RTCCALLBACK(\_RTC\_Free\_hook, (pUserData, 0));
                
                    if (pUserData == NULL)
                        return;
                
                    \_mlock(\_HEAP\_LOCK);  /\* block other threads \*/
                    \_\_TRY
                
                        /\* get a pointer to memory block header \*/
                        pHead = pHdr(pUserData);
                
                         /\* verify block type \*/
                        \_ASSERTE(\_BLOCK\_TYPE\_IS\_VALID(pHead->nBlockUse));
                
                        \_free\_dbg( pUserData, pHead->nBlockUse );
                
                    \_\_FINALLY
                        \_munlock(\_HEAP\_LOCK);  /\* release other threads \*/
                    \_\_END\_TRY\_FINALLY
                
                    return;
                

                }

                #endif /* _DEBUG */

                the code looks like i've passed an invalid param to the delete function... should i not be disposing of this variable, it is not used anywhere else in my code as of yet? or is there another method for disposing of this var?

                M Offline
                M Offline
                MicroVirus
                wrote on last edited by
                #7

                jwalker343 wrote:

                I'm still a bit confused about the TCHAR and WCHAR definitions... they seem to convert themselves... i guess these are one of those "C++ Macros" that i've been reading about?

                These are indeed macro's. The definition of TCHAR sort of goes like:

                #ifdef _UNICODE
                #define TCHAR WCHAR // Unicode is on -> Wide character type
                #else
                #define TCHAR CHAR // Unicode is off -> Normal character type
                #endif

                jwalker343 wrote:

                i figured i could just strcat() the strings in the same line, but i'm still trying to figure out C++

                The thing with TCHARs is that they work very nicely in allowing your code to compile and work both when compiling for Ansi and for Unicode (Wide) character sets. But, there is a catch. You need to make sure all your string function follow the t-pattern. That's why, in tchar.h there are a lot of macro's that switch definition based on whether _UNICODE is true or not. These are the _txyz macro's, such as _tcscat for strcat/wcscat, or _tcslen for strlen or wcslen. If you define all your strings as TCHAR and use the associated _txyz routines, then your code will compile for all character sets without having to change. This does require a slight awareness though. Code like sizeof() can work differently. sizeof always gives the size in 'char', and that's equal to strlen for ansi, but equal to twice the wcslen for unicode (as wcslen gives the amount of wide characters, and each character is 2 bytes (chars) in size). There is a lot of intricacies to C++, certainly when targeting a specific platform, such as Windows. One of those intricacies is tchar.h and all its facets ;) At any rate, you were right in your assumption: you can just use strcat the way you wanted to.

                jwalker343 wrote:

                i've made the changes stated above, but i am now getting a "Debug Assertion Error" on my line:

                Now, to the problem at hand: I think you are mixing two bits of code. The one I gave and the one given by the other poster. You posted a piece of code in the beginning. If you replace exactly that code with the code I posted (and add/remove nothing) then it should work. I think you added a delete[] strPath to the snippet I gave, as per the other posters code. delete[] is necessary when you allocate memory using new[]. However, in this snippet the strPath is a fixed size array (MAX_PATH + 5

                J 1 Reply Last reply
                0
                • M MicroVirus

                  jwalker343 wrote:

                  I'm still a bit confused about the TCHAR and WCHAR definitions... they seem to convert themselves... i guess these are one of those "C++ Macros" that i've been reading about?

                  These are indeed macro's. The definition of TCHAR sort of goes like:

                  #ifdef _UNICODE
                  #define TCHAR WCHAR // Unicode is on -> Wide character type
                  #else
                  #define TCHAR CHAR // Unicode is off -> Normal character type
                  #endif

                  jwalker343 wrote:

                  i figured i could just strcat() the strings in the same line, but i'm still trying to figure out C++

                  The thing with TCHARs is that they work very nicely in allowing your code to compile and work both when compiling for Ansi and for Unicode (Wide) character sets. But, there is a catch. You need to make sure all your string function follow the t-pattern. That's why, in tchar.h there are a lot of macro's that switch definition based on whether _UNICODE is true or not. These are the _txyz macro's, such as _tcscat for strcat/wcscat, or _tcslen for strlen or wcslen. If you define all your strings as TCHAR and use the associated _txyz routines, then your code will compile for all character sets without having to change. This does require a slight awareness though. Code like sizeof() can work differently. sizeof always gives the size in 'char', and that's equal to strlen for ansi, but equal to twice the wcslen for unicode (as wcslen gives the amount of wide characters, and each character is 2 bytes (chars) in size). There is a lot of intricacies to C++, certainly when targeting a specific platform, such as Windows. One of those intricacies is tchar.h and all its facets ;) At any rate, you were right in your assumption: you can just use strcat the way you wanted to.

                  jwalker343 wrote:

                  i've made the changes stated above, but i am now getting a "Debug Assertion Error" on my line:

                  Now, to the problem at hand: I think you are mixing two bits of code. The one I gave and the one given by the other poster. You posted a piece of code in the beginning. If you replace exactly that code with the code I posted (and add/remove nothing) then it should work. I think you added a delete[] strPath to the snippet I gave, as per the other posters code. delete[] is necessary when you allocate memory using new[]. However, in this snippet the strPath is a fixed size array (MAX_PATH + 5

                  J Offline
                  J Offline
                  jwalker343
                  wrote on last edited by
                  #8

                  wow, very helpful... explains why C++ is such a powerful language... it's almost as if the entire language can change pretty quickly depending on all of your own settings... that's crazy!! and the memory allocation seems understandable as well now that you explain it like that... basically if you specifically ask for new memory, you've got to deal with it yourself... Thanks a bunch MicroVirus... i'm looking to release my first CodeProject Article on this project in the coming months... i'll be sure to mention your help!

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups