Behave well with hidden files |
As Windows moves forward, more files and folders will be hidden, to reduce complexity for the user. Your application will need to be aware that some of its files, or system files and folders, may be hidden.
By hiding system-type files, the disk “clutter” that users see can be reduced. Most users don’t need to see DLLs and the page file, so why complicate matters by showing them? You need to make sure that your program is aware that some files are hidden, and can handle hidden files without problems. The easiest way to do this is to always use common file dialogs. The operating system will then handle the display of hidden files according to user preferences and system policy.
The code sample below, adds sub-folders in a given folder to some (undefined) UI element such as a treeview. First we call one of our functions that checks the registry to see if the “Show All Files” option is selected and store the returned TRUE/FALSE value in a local variable. We then loop using FindFirstFile and FindNextFile, checking to see if the file we find is a directory. If it is a directory we then check to see if it has the hidden attribute and if show Hidden Files is FALSE. If this evaluates to TRUE we do nothing, as we don’t want to add the folder. Otherwise, we add the folder to the UI.
#define HIDDEN_SETTINGS_KEY _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced")
HRESULT FindFolders(LPTSTR tszRoot)
{
HRESULT hr = S_OK;
HANDLE hFindFile = NULL;
TCHAR tszNewRoot[MAX_PATH];
BOOL fMoreFiles = FALSE;
BOOL fAddHidden = FALSE;
WIN32_FIND_DATA fdFindFileData;
// Call our function to read show hidden options
// from the registry
fAddHidden = ShowHidden();
if ((NULL == tszRoot) || (_tclen(tszRoot) > MAX_PATH))
{
ASSERT(FALSE):
hr = E_INVALIDARG;
goto _end;
}
_tcscpy(tszNewRoot, tszRoot);
PathAppend(tszNewRoot, _T("*.*"));
//Start search
hFindFile = FindFirstFile(tszNewRoot, &fdFindFileData);
// Nope, nothing there
if (INVALID_HANDLE_VALUE == hFindFile)
{
ASSERT(FALSE);
hr = E_FAIL;
goto _end;
}
else
{
fMoreFiles = TRUE;
}
// Find any other folders
while (fMoreFiles)
{
//see if we're a folder
if(fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// Check to see if this is a hidden folder. And if we are showing hidden folders
// NOTE: we don't deal with hiding system files
if ((fdFindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) && (FALSE == fAddHidden))
{
// Do nothing, because we're not showing hidden folders
}
else
{
// Add item to treeview etc.
}
}
fMoreFiles = FindNextFile(hFindFile, &fdFindFileData);
}
_end:
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// Returns TRUE if the shell Show All Files option is set in the registry
BOOL ShowHidden()
{
HKEY hKey = NULL;
LONG lResult = ERROR_SUCCESS;
DWORD dwShowHidden = NULL;
DWORD dwSize = sizeof(DWORD);
// We don't need full read access, only the right
// to read key values. So, we use KEY_QUERY_VALUE
lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
HIDDEN_SETTINGS_KEY,
NULL,
KEY_QUERY_VALUE,
&hKey
);
// We can't read the settings, assume a default of don't show hidden
if (ERROR_SUCCESS != lResult)
return FALSE;
// Read the settings, if we fail dwShowHidden is 0 and we return FALSE
RegQueryValueEx(hKey,
_T("Hidden"),NULL,NULL,
(LPBYTE) &dwShowHidden,
&dwSize
);
RegCloseKey(hKey);
//Check to see if show all files is set
if (dwShowHidden != 0x00000000)
return TRUE;
else
return FALSE;
}