Game Development Community

dev|Pro Game Development Curriculum

openFileSystemFolder()

by Orion Elenzil · 06/02/2009 (4:02 pm) · 8 comments

a simple function to open up a file system folder window on a given directory

example uses
openFileSystemFolder("c:"); // does what you would expect
openFileSystemFolder("c:/tmp"); // also does what you would expect
openFileSystemFolder("common"); // opens the folder "common" in the current working directory.
openFileSystemFolder("common/foo.txt"); // formats harddrive. just kidding, it does nothing.


this is based on a TGE 1.3.5 codebase.
it works in windows vista (and therefore probably all previous flavours of windows),
but there's only non-functional stubs for Mac and Unix.

the core of this should work on all C-based flavours of torque,
but it might need some tweaking.

platform.h
add this line somewhere in the public section of the Platform struct:
static bool openFileSystemFolder(const char* folderPath);

winWindow.cc
find a nice spot and add this function:
// returns true on success, false otherwise
bool Platform::openFileSystemFolder(const char* folderPath)
{
   // convert forward slashes to backwards ones
   U32 destSize = dStrlen(folderPath) + 1;
   char* dest = strreplace(folderPath, destSize, "/", "");

   // http://msdn.microsoft.com/en-us/library/bb762153(VS.85).aspx
   int ret = (int)ShellExecute(NULL, "explore", dest, NULL, NULL, SW_SHOWNORMAL);

   delete [] dest;

   return ret > 32;
}

macCarbWindow.cc
find a nice place and add this stub:
// returns true on success, false otherwise
bool Platform::openFileSystemFolder(const char* folderPath)
{
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
   
   NSString *nsDir = [NSString stringWithCString:dir encoding:[NSString defaultCStringEncoding]];
   
   BOOL status = [[NSWorkspace sharedWorkspace] selectFile:nil inFileViewerRootedAtPath:nsDir];
   [pool release];
   
   return status;
}

alternate mac implementation:
// returns true on success, false otherwise
bool Platform::openFileSystemFolder(const char* folderPath)
{
   return [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithUTF8String:folderPath]];  
}



x86UNIXWindow.cc
find a nice place and add this stub:
// returns true on success, false otherwise
bool Platform::openFileSystemFolder(const char* folderPath)
{
   Con::errorf("%s() - unimplemented", __FUNCTION__);
   return false;
}

game.cc
add this console function:
ConsoleFunction( openFileSystemFolder, bool, 2, 2, "( path )" )
{
    return Platform::openFileSystemFolder(argv[1]);
}



#1
06/02/2009 (5:46 pm)
OMG THANK YOU!! This is the most helpful thing for me right now. your work is very appreciated!
#2
06/02/2009 (5:48 pm)
sweet! glad it could help !
#3
06/02/2009 (5:51 pm)
return ret == 42;    // empirically determined. not sure what the proper symbol is.
should be
return ret > 32;

From the ShellExecute docs:
Quote:If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure.
#4
06/02/2009 (5:55 pm)
doh, i should have seen that.
i read the "compared to either 32" part and assumed that it was 32 on success, then when the actual value came back as 42 i assumed i'd read "42" as "32".

this is one of the reasons it's good to post code resources,
thanks Alex!

i wonder why they don't return S_OK like many other API calls.
#5
06/02/2009 (6:02 pm)
Because that might be consistent!

Nah, I'm sure there's actually a decent reason for it. Raymond Chen would probably know.

And here, have a completely untested Mac version of that function
return [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithUTF8String:folderPath]];

Edit: This mac version will open any file or folder you hand it, not just folders.
#6
06/03/2009 (10:02 am)
thanks Alex.
it turns out we ("we" being randall meyer) had already implemented something like this in the mac side. I included both that version and yours to the resource body. i can't pretend to have any idea what the differences may be - that doesn't even look like C to me!
#7
06/03/2009 (10:45 am)
Well, your implementation will actually just open the folder and won't leak memory in TGE/TGB (TGEA is a real cocoa app and already has an autorelease pool), so there's a couple of differences :).
#8
06/03/2009 (11:20 am)
memory leak, schmemory leak, i always say.