0

I have a class which collects all paths to .txt files of a given folder and stores them into a vector. Most of the functions I use require the usage of TCHAR* to get/set current directory and so on.

The class looks like this:

typedef std::basic_string<TCHAR> tstring;
class folderManager
{
private:
    TCHAR searchTemplate[MAX_PATH]; 
    TCHAR directory[MAX_PATH];          

    WIN32_FIND_DATA ffd;
    HANDLE hFind;        

    vector<tstring> folderCatalog; 
    vector<tstring> fileNames;     

    bool succeeded; 

public:
    // get/set methods and so on...
};
// Changed TCHAR* dir to tstring dir
void folderManager::setDirectory(tstring dir)
{
    HANDLE hFind = NULL;
    succeeded = false;

    folderCatalog.clear();
    fileNames.clear();
    // Added .c_str()
    SetCurrentDirectory(dir.c_str());
    GetCurrentDirectoryW(MAX_PATH, directory);

    TCHAR fullName[MAX_PATH]; 

    StringCchCat(directory, MAX_PATH, L"\\");

    StringCchCopy(searchTemplate, MAX_PATH, directory); 
    StringCchCat(searchTemplate, MAX_PATH, L"*.txt");

    hFind = FindFirstFile(searchTemplate, &ffd);    

    if (GetLastError() == ERROR_FILE_NOT_FOUND) 
    {
        FindClose(hFind);
        return;
    }
    do
    {
        StringCchCopy(fullName, MAX_PATH, directory);
        StringCchCat(fullName, MAX_PATH, ffd.cFileName);

        folderCatalog.push_back(fullName);  
        fileNames.push_back(ffd.cFileName); 
    }
    while (FindNextFile(hFind, &ffd) != 0);

    FindClose(hFind);
    succeeded = true;
}

This is where I need to do the conversion of System::String^ to TCHAR*

private: System::Void dienuFolderisToolStripMenuItem_Click(System::Object^
    sender, System::EventArgs^  e)
{
    FolderBrowserDialog^ dialog;
    dialog = gcnew System::Windows::Forms::FolderBrowserDialog;

    System::Windows::Forms::DialogResult result = dialog->ShowDialog();
    if (result == System::Windows::Forms::DialogResult::OK)
    {   
                     // Conversion is now working.          
         tstring path = marshal_as<tstring>(dialog->SelectedPath);
         folder->setDirectory(path);
    }
}
Edd
  • 1,982
  • 2
  • 21
  • 29
  • 1
    Just use wstring everywhere. All the versions of Windows that can run modern versions of .NET have unicode APIs. – Ben Voigt May 04 '14 at 06:34
  • What Ben is saying is, almost certainly, [you don't need TCHAR](http://stackoverflow.com/q/4205809/2226988). – Tom Blodget May 04 '14 at 18:50

1 Answers1

0

marsha_as "Performs the marshaling on a specific data object to convert it between a managed and a native data type". Here there is the table for possible type conversion.

I use it this way:

marshal_as<std::wstring>(value)

TCHAR can be char or wchar_t, both of them present in marshal_as specialization, I suppose you need to point TCHAR* as template parameter:

TCHAR* result = marshal_as<TCHAR*>(value)

Actually MSDN says that you have to use it this way:

#include <msclr\marshal.h>

using namespace System;
using namespace msclr::interop;

int main(array<System::String ^> ^args)
{
    System::String^ managedString = gcnew System::String("Hello World!!!");

    marshal_context ^ context = gcnew marshal_context();
    const wchar_t* nativeString = context->marshal_as<const wchar_t*>(managedString);
    //use nativeString
    delete context;

    return 0;
}
Serhiy
  • 1,332
  • 1
  • 16
  • 24
  • I've tried the first method you've mentioned, however I came to a problem of converting wstring to TCHAR*. The second option gives me a long error (This conversion is not supported by the library...) – Edd May 03 '14 at 14:22
  • std::wstring and TCHAR* are both native types, you don't need to use marshal_as in this case. Your question was how to convert String^ to TCHAR*? – Serhiy May 03 '14 at 14:25
  • I got it working, going to edit the main post for the solution, thanks! – Edd May 03 '14 at 14:38