/*
----------------------------------------------------------------
Filename.....: apifolders.cc
ClassName....: apifolders
Purpose......: object to hold operating system folders.
Programmer...: Rick Miller
Date.........: February 06, 2002.
Notes........: See Notes below.
Written for..: dB2K 0.1 and newer.
Rev. History.: See Revisions below.
Dependencies.: None.
Calls........: None.
Called by....: Any.
Usage........: set procedure to apifolders.cc additive
Example......: See Example below.
----------------------------------------------------------------
Example:
----------------------------------------------------------------
oRef = new apifolders()
inspect(oRef) // to view properties
oRef.release()
oRef := null
close procedure apifolders.cc
----------------------------------------------------------------
Properties:
----------------------------------------------------------------
// common folders.
commonfiles programfiles\Common Files
current current folder
fonts windows\Fonts
programfiles boot root\Program Files
system windows system folder
temp tmp or temp in that order
windows windows folder
// all user folders.
allappdata All Users\Application Data
alldesktop All Users\Desktop
alldocuments All Users\My Documents
allfavorites All Users\Favorites
allmusic All Users\My Documents\My Music
allpictures All Users\My Documents\My Pictures
allprograms All Users\Start Menu\Programs
allstartup All Users\Start Menu\Programs\Startup
alltemplates All Users\Templates
// user specific folders.
appdata User\Application Data
appdatalocal User\Local Settings\Application Data
cookies User\Cookies
desktop User\Desktop
favorites User\Favorites
history User\Local Settings\History
mydocuments User\My Documents or User\Personal
mymusic User\My Documents\My Music
mypictures User\My Documents\My Pictures
programs User\Start Menu\Programs
recent User\Recent
sendto User\Start Menu\Sendto
startup User\Start Menu\Programs\StartUp
templates User\Templates
----------------------------------------------------------------
Methods:
----------------------------------------------------------------
close calls release.
getLongPath returns long path for a passed parameter.
release release object from memory.
----------------------------------------------------------------
Notes:
----------------------------------------------------------------
1) shfolder.dll is distributed with IE 5 and newer.
2) The constants in the header were derived from shlobj.h.
They were renamed to avoid conflicts.
3) You may want to copy and paste the portion of the
header from #ifndef to #endif into rmmshfolder.h.
rmmshfolder.h can then be used with an #include
where ever needed.
4) properties do NOT have a trailing backslash ("\")
testing done on WinXP, Win2000, Win98, Win95.
----------------------------------------------------------------
Revisions:
----------------------------------------------------------------
October 30, 2006
1) fix for bug in x_Find method.
2) correction for appdata property.
3) correction for desktop property.
4) added appdatalocal property.
5) changed code to use constants.
-------------------------------------------------------------
April 21, 2005 - cleaned code.
-------------------------------------------------------------
February 10, 2005 - renamed all external functions.
-------------------------------------------------------------
January 01, 2005 - verify externs, revisited all methods.
-------------------------------------------------------------
September 10,2003 - now compatible with Win95.
-------------------------------------------------------------
August 07, 2003 - revised for win 95.
-------------------------------------------------------------
May 09, 2003 - added getLongPath call.
-------------------------------------------------------------
March 31, 2003 - revised release method.
-------------------------------------------------------------
April 03, 2002 - added shgetfolderpath from
newsgroup posting
by Christopher F. Neumann.
-------------------------------------------------------------
February 19, 2002 - documentation.
----------------------------------------------------------------
*/
#ifndef _RMMSHFOLDER_H_
#define _RMMSHFOLDER_H_
#define RMMCSIDL_FLAG_MASK 0xFF00 // mask for all possible flag values
// custom constants.
#define RMMCSIDL_CURRENT 0xFF01 // current directory (custom).
#define RMMCSIDL_TEMP 0xFF02 // tmp/temp directory (custom).
#define RMMCSIDL_TMP RMMCSIDL_TEMP // tmp/temp directory (custom).
// end of custom constants.
// Note: not all folders are guaranteed to exist.
#define RMMCSIDL_DESKTOP 0x0000 // <desktop>
#define RMMCSIDL_INTERNET 0x0001 // Internet Explorer (icon on desktop)
#define RMMCSIDL_PROGRAMS 0x0002 // Start Menu\Programs
#define RMMCSIDL_CONTROLS 0x0003 // My Computer\Control Panel
#define RMMCSIDL_PRINTERS 0x0004 // My Computer\Printers
#define RMMCSIDL_PERSONAL 0x0005 // My Documents
#define RMMCSIDL_FAVORITES 0x0006 // <user name>\Favorites
#define RMMCSIDL_STARTUP 0x0007 // Start Menu\Programs\Startup
#define RMMCSIDL_RECENT 0x0008 // <user name>\Recent
#define RMMCSIDL_SENDTO 0x0009 // <user name>\SendTo
#define RMMCSIDL_BITBUCKET 0x000a // <desktop>\Recycle Bin
#define RMMCSIDL_STARTMENU 0x000b // <user name>\Start Menu
// Note: using PERSONAL for MYDOCUMENTS is correct here.
#define RMMCSIDL_MYDOCUMENTS RMMCSIDL_PERSONAL // 0x000c is for the PIDL of the "My Documents" desktop icon
#define RMMCSIDL_MYMUSIC 0x000d // "My Music" folder
#define RMMCSIDL_MYVIDEO 0x000e // "My Videos" folder
#define RMMCSIDL_DESKTOPDIRECTORY 0x0010 // <user name>\Desktop
#define RMMCSIDL_DRIVES 0x0011 // My Computer
#define RMMCSIDL_NETWORK 0x0012 // Network Neighborhood (My Network Places)
#define RMMCSIDL_NETHOOD 0x0013 // <user name>\nethood
#define RMMCSIDL_FONTS 0x0014 // windows\fonts
#define RMMCSIDL_TEMPLATES 0x0015 // <user name>\Templates
#define RMMCSIDL_COMMON_STARTMENU 0x0016 // All Users\Start Menu
#define RMMCSIDL_COMMON_PROGRAMS 0X0017 // All Users\Start Menu\Programs
#define RMMCSIDL_COMMON_STARTUP 0x0018 // All Users\Startup
#define RMMCSIDL_COMMON_DESKTOPDIRECTORY 0x0019 // All Users\Desktop
#define RMMCSIDL_APPDATA 0x001a // <user name>\Application Data
#define RMMCSIDL_PRINTHOOD 0x001b // <user name>\PrintHood
#define RMMCSIDL_LOCAL_APPDATA 0x001c // <user name>\Local Settings\Application Data (non roaming)
#define RMMCSIDL_ALTSTARTUP 0x001d // non localized startup
#define RMMCSIDL_COMMON_ALTSTARTUP 0x001e // All Users\Start Menu\Programs\startup
#define RMMCSIDL_COMMON_FAVORITES 0x001f // All Users\Start Menu\Favorites
#define RMMCSIDL_INTERNET_CACHE 0x0020 // <user name>\Local Settings\Temporary Internet Files
#define RMMCSIDL_COOKIES 0x0021 // <user name>\Cookies
#define RMMCSIDL_HISTORY 0x0022 // <user name>\Local Settings\History
#define RMMCSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
#define RMMCSIDL_WINDOWS 0x0024 // GetWindowsDirectory()
#define RMMCSIDL_SYSTEM 0x0025 // GetSystemDirectory()
#define RMMCSIDL_PROGRAM_FILES 0x0026 // C:\Program Files
#define RMMCSIDL_MYPICTURES 0x0027 // "My Pictures" folder
#define RMMCSIDL_PROFILE 0x0028 // <user name> %USERPROFILE%
#define RMMCSIDL_SYSTEMX86 0x0029 // x86 system directory on RISC
#define RMMCSIDL_PROGRAM_FILESX86 0x002a // x86 C:\Program Files on RISC
#define RMMCSIDL_PROGRAM_FILES_COMMON 0x002b // C:\Program Files\Common
#define RMMCSIDL_PROGRAM_FILES_COMMONX86 0x002c // x86 Program Files\Common on RISC
#define RMMCSIDL_COMMON_TEMPLATES 0x002d // All Users\Templates
#define RMMCSIDL_COMMON_DOCUMENTS 0x002e // All Users\Documents
#define RMMCSIDL_COMMON_ADMINTOOLS 0x002f // All Users\Start Menu\Programs\Administrative Tools
#define RMMCSIDL_ADMINTOOLS 0x0030 // <user name>\Start Menu\Programs\Administrative Tools
#define RMMCSIDL_CONNECTIONS 0x0031 // Network and Dial-up Connections
#define RMMCSIDL_COMMON_MUSIC 0x0035 // All Users\Documents\My Music
#define RMMCSIDL_COMMON_PICTURES 0x0036 // All Users\Documents\My Pictures
#define RMMCSIDL_COMMON_VIDEO 0x0037 // All Users\Documents\My Video
#define RMMCSIDL_RESOURCES 0x0038 // windows\Resource
#define RMMCSIDL_RESOURCES_LOCALIZED 0x0039 // Localized Resource Direcotry
#define RMMCSIDL_COMMON_OEM_LINKS 0x003a // Links to All Users OEM specific apps
#define RMMCSIDL_CDBURN_AREA 0x003b // <user name>\Local Settings\Application Data\Microsoft\CD Burning
#endif // endif for _RMMSHFOLDER_H_
#define MAXPATH (260)
#define APIFOLDERS_PUBLISHERINFO "Rick Miller"
#define APIFOLDERS_VERSIONINFO "6.1030"
//---------------------------------------------------------------//
// apifolders constructor.
//---------------------------------------------------------------//
class apifolders
// protected methods
protect x_Assign, x_Backslashtest, x_Find, x_Get,;
x_InitExterns, x_Special, x_SpecialFolders
class::x_InitExterns() // initialize externs.
class::x_Assign() // assign properties.
this.versioninfo = APIFOLDERS_VERSIONINFO
this.publishinfo = APIFOLDERS_PUBLISHERINFO
//------------------------------------------------------------//
// end of constructor - methods below.
//------------------------------------------------------------//
// un-protected method - call to release.
function close
this.release()
return
//------------------------------------------------------------//
// un-protected method - return the long path for cPath.
function getLongPath(cPath)
Local cRet, n
n = 0
cRet = ""
if type("RMM_GetLongPathName") == "FP"
n := MAXPATH
cRet := space(n)
// next line returns number of chars
// placed into cRet not counting the chr(0) terminator.
n := RMM_GetLongPathName(cPath, cRet, n)
endif
return iif(n == 0, "" + cPath, left(cRet, n))
//------------------------------------------------------------//
// un-protected method - release object from memory.
function release
// NOTE: PLUS 2.01 or newer may raise an exception on
// release object so the method is wrapped in a
// try/endtry construct.
try
release object this
catch(exception e)
endtry
return true
//------------------------------------------------------------//
// protected method - assign properties.
function x_Assign
this.current = class::getLongPath( ;
class::x_Get(RMMCSIDL_CURRENT))
this.system = class::getLongPath( ;
class::x_Get(RMMCSIDL_SYSTEM))
this.temp = class::getLongPath( ;
class::x_Get(RMMCSIDL_TEMP))
this.windows = class::getLongPath( ;
class::x_Get(RMMCSIDL_WINDOWS))
if file(this.system + "\shfolder.dll")
// shfolder.dll comes with Internet Explorer 5.01 or newer.
if not type("RMM_SHGetFolderPath") == "FP"
extern CLONG RMM_SHGetFolderPath( ;
CHANDLE, CINT, CHANDLE, CULONG, CSTRING) ;
shfolder.dll from "SHGetFolderPathA"
endif
endif
if type("RMM_SHGetFolderPath") == "FP"
class::x_SpecialFolders()
else
class::x_Special()
endif
this.tempapp = "" + this.temp
return true
//------------------------------------------------------------//
// protected method - remove any trailing backslash
function x_Backslashtest(cPath)
if cPath.right(1) == "\"
// remove trailing backslash.
cPath := cPath.left(cPath.length - 1)
endif
return "" + cPath
//------------------------------------------------------------//
// protected method - return the path for nFold.
function x_Find(nFold)
Local cRet, n
n = MAXPATH
cRet = space(n)
// next line returns 0 for success.
n := RMM_SHGetFolderPath(null, nFold, 0, null, cRet)
if n == 0
// cRet holds the folder in a long name.
else
cRet := ""
endif
return "" + cRet
//------------------------------------------------------------//
// protected method - return the path for nFold.
function x_Get(nFold)
Local cRet, n
n = MAXPATH
cRet = space(n)
if nFold == RMMCSIDL_CURRENT
n := RMM_GetCurrentDirectory(n, cRet)
elseif nFold == RMMCSIDL_SYSTEM
n := RMM_GetSystemDirectory(cRet, n)
elseif nFold == RMMCSIDL_TEMP
n := RMM_GetTempPath(n, cRet)
elseif nFold == RMMCSIDL_WINDOWS
n := RMM_GetWindowsDirectory(cRet, n)
else
n := 0
endif
// cRet holds the folder in a short name.
return iif(n > 0, class::x_Backslashtest(cRet.left(n)), "")
//------------------------------------------------------------//
// protected method - declare functions external to dBASE.
function x_InitExterns
if not type("RMM_GetCurrentDirectory") == "FP"
extern CULONG RMM_GetCurrentDirectory(CULONG, CSTRING) ;
kernel32 from "GetCurrentDirectoryA"
endif
if not type("RMM_GetLongPathName") == "FP"
try
// requires win98 or winNT 4.0 SP3 and above.
extern CULONG RMM_GetLongPathName( ;
CSTRING, CSTRING, CULONG) ;
kernel32 from "GetLongPathNameA"
catch(exception e)
endtry
endif
if not type("RMM_GetSystemDirectory") == "FP"
extern CUINT RMM_GetSystemDirectory(CSTRING, CUINT) ;
kernel32 from "GetSystemDirectoryA"
endif
if not type("RMM_GetTempPath") == "FP"
extern CULONG RMM_GetTempPath(CULONG, CSTRING) ;
kernel32 from "GetTempPathA"
endif
if not type("RMM_GetWindowsDirectory") == "FP"
extern CUINT RMM_GetWindowsDirectory(CSTRING, CUINT) ;
kernel32 from "GetWindowsDirectoryA"
endif
return true
//------------------------------------------------------------//
// protected method - assign special folders for win95.
// Note: these folders are for Windows English version.
function x_Special
Local cAll, cRoot, cWin
cWin = (this.windows)
cRoot = cWin.left(cWin.indexof("\"))
cAll = cWin + "\All Users"
this.appdata = (cWin + "\Application Data")
this.appdatalocal = (cWin + "\Application Data")
this.commonfiles = (cRoot + "\Program Files\Common Files")
this.cookies = ""
this.desktop = (cWin + "\Desktop")
this.favorites = (cWin + "\Favorites")
this.fonts = (cWin + "\Fonts")
this.history = (cWin + "\History")
this.mydocuments = (cRoot + "\My Documents")
this.mymusic = (cRoot + "\My Documents\My Music")
this.mypictures = (cRoot + "\My Documents\My Pictures")
this.programfiles = (cRoot + "\Program Files")
this.programs = (cWin + "\Start Menu\Programs")
this.recent = (cWin + "\Recent")
// this.recycle = this.x_Find(10) // may not work
this.sendto = (cWin + "\SendTo")
this.startup = (cWin + "\Start Menu\Programs\Startup")
this.templates = ""
this.allappdata = (cAll + "\Application Data")
this.alldesktop = (cWin + "\Desktop")
this.alldocuments = (cRoot + "\My Documents")
this.allfavorites = (cWin + "\Favorites")
this.allmusic = (cRoot + "\My Documents\My Music")
this.allpictures = (cRoot + "\My Documents\My Pictures")
this.allprograms = (cWin + "\Start Menu\Programs")
this.allstartup = (cWin + "\Start Menu\Programs\Startup")
this.alltemplates = ""
return
//------------------------------------------------------------//
// protected method - assign special folders.
function x_SpecialFolders
// not user specific folders.
this.commonfiles = class::x_Find(RMMCSIDL_PROGRAM_FILES_COMMON)
this.fonts = class::x_Find(RMMCSIDL_FONTS)
this.programfiles = class::x_Find(RMMCSIDL_PROGRAM_FILES)
// user (userprofile) folders.
this.appdata = class::x_Find(RMMCSIDL_APPDATA)
this.appdatalocal = class::x_Find(RMMCSIDL_LOCAL_APPDATA)
this.cookies = class::x_Find(RMMCSIDL_COOKIES)
this.desktop = class::x_Find(RMMCSIDL_DESKTOPDIRECTORY)
this.favorites = class::x_Find(RMMCSIDL_FAVORITES)
this.history = class::x_Find(RMMCSIDL_HISTORY)
this.mydocuments = class::x_Find(RMMCSIDL_PERSONAL)
this.mymusic = class::x_Find(RMMCSIDL_MYMUSIC)
this.mypictures = class::x_Find(RMMCSIDL_MYPICTURES)
this.programs = class::x_Find(RMMCSIDL_PROGRAMS)
this.recent = class::x_Find(RMMCSIDL_RECENT)
// this.recycle = this.x_Find(RMMCSIDL_BITBUCKET) // may not work
this.sendto = class::x_Find(RMMCSIDL_SENDTO)
this.startup = class::x_Find(RMMCSIDL_STARTUP)
this.templates = class::x_Find(RMMCSIDL_TEMPLATES)
// all user folders.
Local cVal
cVal = class::x_Find(RMMCSIDL_COMMON_APPDATA)
this.allappdata = iif(empty(cVal), this.appdata, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_DESKTOPDIRECTORY)
this.alldesktop = iif(empty(cVal), this.desktop, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_DOCUMENTS)
this.alldocuments = iif(empty(cVal), this.mydocuments, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_FAVORITES)
this.allfavorites = iif(empty(cVal), this.favorites, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_MUSIC)
this.allmusic = iif(empty(cVal), this.mymusic, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_PICTURES)
this.allpictures = iif(empty(cVal), this.mypictures, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_PROGRAMS)
this.allprograms = iif(empty(cVal), this.programfiles, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_STARTUP)
this.allstartup = iif(empty(cVal), this.startup, cVal)
cVal = class::x_Find(RMMCSIDL_COMMON_TEMPLATES)
this.alltemplates = iif(empty(cVal), this.templates, cVal)
return
endclass
//---------------------------------------------------------------//
// end of apifolders.
//---------------------------------------------------------------//