|
|
/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright 1998 Microsoft Corporation. All Rights Reserved. **************************************************************************/
/**************************************************************************
File: Utility.cpp Description: Utility function implementation
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "Utility.h"
#include "ShlFldr.h"
#include "resource.h"
#include "Commands.h"
/**************************************************************************
global variables **************************************************************************/
#define MAIN_KEY_STRING (TEXT("Software\\SampleView"))
#define VALUE_STRING (TEXT("Display Settings"))
#define DISPLAY_SETTINGS_COUNT 1
/**************************************************************************
CompareItems() **************************************************************************/
int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) { CShellFolder *pFolder = (CShellFolder*)lpData;
if(!pFolder) return 0;
HRESULT hr = pFolder->CompareIDs(0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2);
return (SHORT)HRESULT_CODE(hr); }
/**************************************************************************
SaveGlobalSettings() **************************************************************************/
BOOL SaveGlobalSettings(void) { HKEY hKey; LONG lResult; DWORD dwDisp;
lResult = RegCreateKeyEx( HKEY_CURRENT_USER, MAIN_KEY_STRING, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisp);
if(lResult != ERROR_SUCCESS) return FALSE;
//create an array to put our data in
DWORD dwArray[DISPLAY_SETTINGS_COUNT]; dwArray[0] = g_nColumn;
//save the last printer selected
lResult = RegSetValueEx( hKey, VALUE_STRING, 0, REG_BINARY, (LPBYTE)dwArray, sizeof(dwArray));
RegCloseKey(hKey);
if(lResult != ERROR_SUCCESS) return FALSE;
return TRUE; }
/**************************************************************************
GetGlobalSettings() **************************************************************************/
VOID GetGlobalSettings(VOID) { LPITEMIDLIST pidl = NULL;
g_nColumn = INITIAL_COLUMN_SIZE;
LoadString(g_hInst, IDS_EXT_TITLE, g_szExtTitle, TITLE_SIZE);
*g_szStoragePath = 0; SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl);
if(pidl) { IMalloc *pMalloc;
SHGetPathFromIDList(pidl, g_szStoragePath); SHGetMalloc(&pMalloc); if(pMalloc) { pMalloc->Free(pidl); pMalloc->Release(); } } else { GetWindowsDirectory(g_szStoragePath, MAX_PATH); }
SmartAppendBackslash(g_szStoragePath); lstrcat(g_szStoragePath, g_szExtTitle); SmartAppendBackslash(g_szStoragePath); CreateDirectory(g_szStoragePath, NULL);
HKEY hKey; LRESULT lResult; lResult = RegOpenKeyEx( HKEY_CURRENT_USER, MAIN_KEY_STRING, 0, KEY_ALL_ACCESS, &hKey);
if(lResult != ERROR_SUCCESS) return;
//create an array to put our data in
DWORD dwArray[DISPLAY_SETTINGS_COUNT]; DWORD dwType; DWORD dwSize = sizeof(dwArray);
//get the saved data
lResult = RegQueryValueEx( hKey, VALUE_STRING, NULL, &dwType, (LPBYTE)dwArray, &dwSize);
RegCloseKey(hKey);
if(lResult != ERROR_SUCCESS) return;
g_nColumn = dwArray[0]; }
/**************************************************************************
CreateImageLists() **************************************************************************/
VOID CreateImageLists(VOID) { int cx; int cy;
cx = GetSystemMetrics(SM_CXSMICON); cy = GetSystemMetrics(SM_CYSMICON);
if(g_himlSmall) ImageList_Destroy(g_himlSmall);
//set the small image list
g_himlSmall = ImageList_Create(cx, cy, ILC_COLORDDB | ILC_MASK, 3, 0);
if(g_himlSmall) { HICON hIcon; TCHAR szFolder[MAX_PATH]; SHFILEINFO sfi; //add the item icon
hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR); ImageList_AddIcon(g_himlSmall, hIcon);
//add the closed folder icon
GetWindowsDirectory(szFolder, MAX_PATH); SHGetFileInfo( szFolder, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON); ImageList_AddIcon(g_himlSmall, sfi.hIcon);
//add the open folder icon
SHGetFileInfo( szFolder, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_OPENICON); ImageList_AddIcon(g_himlSmall, sfi.hIcon); }
if(g_himlLarge) ImageList_Destroy(g_himlLarge);
cx = GetSystemMetrics(SM_CXICON); cy = GetSystemMetrics(SM_CYICON);
//set the large image list
g_himlLarge = ImageList_Create(cx, cy, ILC_COLORDDB | ILC_MASK, 4, 0);
if(g_himlLarge) { HICON hIcon; TCHAR szFolder[MAX_PATH]; SHFILEINFO sfi; //add the item icon
hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR); ImageList_AddIcon(g_himlLarge, hIcon);
//add the closed folder icon
GetWindowsDirectory(szFolder, MAX_PATH); ZeroMemory(&sfi, sizeof(sfi)); SHGetFileInfo( szFolder, 0, &sfi, sizeof(sfi), SHGFI_ICON); ImageList_AddIcon(g_himlLarge, sfi.hIcon);
//add the open folder icon
GetWindowsDirectory(szFolder, MAX_PATH); ZeroMemory(&sfi, sizeof(sfi)); SHGetFileInfo( szFolder, 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_OPENICON); ImageList_AddIcon(g_himlLarge, sfi.hIcon); }
}
/**************************************************************************
AddIconImageLists() **************************************************************************/ int AddIconImageList(HIMAGELIST himl, LPCTSTR szImagePath) { if(himl) { HICON hIcon; //add the item icon
hIcon = (HICON)LoadImage(NULL, szImagePath, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_LOADFROMFILE | LR_DEFAULTSIZE); return ImageList_AddIcon(himl, hIcon); } else return -1; }
/**************************************************************************
DestroyImageLists() **************************************************************************/
VOID DestroyImageLists(VOID) { if(g_himlSmall) ImageList_Destroy(g_himlSmall);
if(g_himlLarge) ImageList_Destroy(g_himlLarge); }
/**************************************************************************
WideCharToLocal() **************************************************************************/
int WideCharToLocal(LPTSTR pLocal, LPWSTR pWide, DWORD dwChars) { *pLocal = 0;
#ifdef UNICODE
lstrcpyn(pLocal, pWide, dwChars); #else
WideCharToMultiByte( CP_ACP, 0, pWide, -1, pLocal, dwChars, NULL, NULL); #endif
return lstrlen(pLocal); }
/**************************************************************************
LocalToWideChar() **************************************************************************/
int LocalToWideChar(LPWSTR pWide, LPTSTR pLocal, DWORD dwChars) { *pWide = 0;
#ifdef UNICODE
lstrcpyn(pWide, pLocal, dwChars); #else
MultiByteToWideChar( CP_ACP, 0, pLocal, -1, pWide, dwChars); #endif
return lstrlenW(pWide); }
/**************************************************************************
LocalToAnsi()
**************************************************************************/
int LocalToAnsi(LPSTR pAnsi, LPCTSTR pLocal, DWORD dwChars) { *pAnsi = 0;
#ifdef UNICODE
WideCharToMultiByte( CP_ACP, 0, pLocal, -1, pAnsi, dwChars, NULL, NULL); #else
lstrcpyn(pAnsi, pLocal, dwChars); #endif
return lstrlenA(pAnsi); }
/**************************************************************************
SmartAppendBackslash()
**************************************************************************/
VOID SmartAppendBackslash(LPTSTR pszPath) { if(*(pszPath + lstrlen(pszPath) - 1) != '\\') lstrcat(pszPath, TEXT("\\")); }
/**************************************************************************
BuildDataFileName()
**************************************************************************/
int BuildDataFileName(LPTSTR pszDataFile, LPCTSTR pszPath, DWORD dwChars) { if(dwChars < (DWORD)(lstrlen(pszPath) + 1 + lstrlen(c_szDataFile))) return 0;
if(IsBadWritePtr(pszDataFile, dwChars)) return 0;
lstrcpy(pszDataFile, pszPath); SmartAppendBackslash(pszDataFile); lstrcat(pszDataFile, c_szDataFile);
return lstrlen(pszDataFile); }
/**************************************************************************
AnsiToLocal()
**************************************************************************/
int AnsiToLocal(LPTSTR pLocal, LPSTR pAnsi, DWORD dwChars) { *pLocal = 0;
#ifdef UNICODE
MultiByteToWideChar( CP_ACP, 0, pAnsi, -1, pLocal, dwChars); #else
lstrcpyn(pLocal, pAnsi, dwChars); #endif
return lstrlen(pLocal); }
/**************************************************************************
GetTextFromSTRRET()
**************************************************************************/
BOOL GetTextFromSTRRET( IMalloc * pMalloc, LPSTRRET pStrRet, LPCITEMIDLIST pidl, LPTSTR pszText, DWORD dwSize) { if(IsBadReadPtr(pStrRet, sizeof(UINT))) return FALSE;
if(IsBadWritePtr(pszText, dwSize)) return FALSE;
switch(pStrRet->uType) { case STRRET_CSTR: AnsiToLocal(pszText, pStrRet->cStr, dwSize); break;
case STRRET_OFFSET: lstrcpyn(pszText, (LPTSTR)(((LPBYTE)pidl) + pStrRet->uOffset), dwSize); break;
case STRRET_WSTR: { WideCharToLocal(pszText, pStrRet->pOleStr, dwSize);
if(!pMalloc) { SHGetMalloc(&pMalloc); } else { pMalloc->AddRef(); } if(pMalloc) { pMalloc->Free(pStrRet->pOleStr); pMalloc->Release(); } } break; default: return FALSE; }
return TRUE; }
/**************************************************************************
IsViewWindow()
**************************************************************************/
BOOL IsViewWindow(HWND hWnd) { if(!hWnd) return FALSE;
TCHAR szClass[MAX_PATH] = TEXT("");
GetClassName(hWnd, szClass, MAX_PATH);
if(0 == lstrcmpi(szClass, NS_CLASS_NAME)) return TRUE;
return FALSE; }
/**************************************************************************
DeleteDirectory()
**************************************************************************/
BOOL DeleteDirectory(LPCTSTR pszDir) { BOOL fReturn = FALSE; HANDLE hFind; WIN32_FIND_DATA wfd; TCHAR szTemp[MAX_PATH];
lstrcpy(szTemp, pszDir); SmartAppendBackslash(szTemp); lstrcat(szTemp, TEXT("*.*")); hFind = FindFirstFile(szTemp, &wfd);
if(INVALID_HANDLE_VALUE != hFind) { do { if(lstrcmpi(wfd.cFileName, TEXT(".")) && lstrcmpi(wfd.cFileName, TEXT(".."))) { //build the path of the directory or file found
lstrcpy(szTemp, pszDir); SmartAppendBackslash(szTemp); lstrcat(szTemp, wfd.cFileName);
if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) { //we found a directory - call this function recursively
DeleteDirectory(szTemp); } else { /*
We found a file. Only delete the data file to prevent us from deleteting something that the user has placed in the folder. */ if(0 == lstrcmpi(wfd.cFileName, c_szDataFile)) { DeleteFile(szTemp); } } } } while(FindNextFile(hFind, &wfd));
FindClose(hFind);
/*
If this fails it means the directory is not empty, so just remove our attributes so the enumerator won't see it. */ fReturn = RemoveDirectory(pszDir); if(!fReturn) { DWORD dwAttr = GetFileAttributes(pszDir); dwAttr &= ~FILTER_ATTRIBUTES; fReturn = SetFileAttributes(pszDir, dwAttr); } }
return fReturn; }
/**************************************************************************
CreatePrivateClipboardData()
**************************************************************************/
HGLOBAL CreatePrivateClipboardData( LPITEMIDLIST pidlParent, LPITEMIDLIST *aPidls, UINT uItemCount, BOOL fCut) { HGLOBAL hGlobal = NULL; LPPRIVCLIPDATA pData; UINT iCurPos; UINT cbPidl; UINT i; CPidlMgr *pPidlMgr;
pPidlMgr = new CPidlMgr();
if(!pPidlMgr) return NULL;
//get the size of the parent folder's PIDL
cbPidl = pPidlMgr->GetSize(pidlParent);
//get the total size of all of the PIDLs
for(i = 0; i < uItemCount; i++) { cbPidl += pPidlMgr->GetSize(aPidls[i]); }
/*
Find the end of the PRIVCLIPDATA structure. This is the size of the PRIVCLIPDATA structure itself (which includes one element of aoffset) plus the additional number of elements in aoffset. */ iCurPos = sizeof(PRIVCLIPDATA) + (uItemCount * sizeof(UINT));
/*
Allocate the memory for the PRIVCLIPDATA structure and it's variable length members. */ hGlobal = GlobalAlloc(GHND | GMEM_SHARE, (DWORD) (iCurPos + // size of the PRIVCLIPDATA structure and the additional aoffset elements
(cbPidl + 1))); // size of the pidls
if (NULL == hGlobal) return (hGlobal);
pData = (LPPRIVCLIPDATA)GlobalLock(hGlobal);
if(pData) { pData->fCut = fCut; pData->cidl = uItemCount + 1; pData->aoffset[0] = iCurPos;
//add the PIDL for the parent folder
cbPidl = pPidlMgr->GetSize(pidlParent); CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)pidlParent, cbPidl); iCurPos += cbPidl;
for(i = 0; i < uItemCount; i++) { //get the size of the PIDL
cbPidl = pPidlMgr->GetSize(aPidls[i]);
//fill out the members of the PRIVCLIPDATA structure.
pData->aoffset[i + 1] = iCurPos;
//copy the contents of the PIDL
CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)aPidls[i], cbPidl);
//set up the position of the next PIDL
iCurPos += cbPidl; } GlobalUnlock(hGlobal); }
delete pPidlMgr;
return (hGlobal); }
/**************************************************************************
CreateShellIDList()
**************************************************************************/
HGLOBAL CreateShellIDList( LPITEMIDLIST pidlParent, LPITEMIDLIST *aPidls, UINT uItemCount) { HGLOBAL hGlobal = NULL; LPIDA pData; UINT iCurPos; UINT cbPidl; UINT i; CPidlMgr *pPidlMgr;
pPidlMgr = new CPidlMgr();
if(!pPidlMgr) return NULL;
//get the size of the parent folder's PIDL
cbPidl = pPidlMgr->GetSize(pidlParent);
//get the total size of all of the PIDLs
for(i = 0; i < uItemCount; i++) { cbPidl += pPidlMgr->GetSize(aPidls[i]); }
/*
Find the end of the CIDA structure. This is the size of the CIDA structure itself (which includes one element of aoffset) plus the additional number of elements in aoffset. */ iCurPos = sizeof(CIDA) + (uItemCount * sizeof(UINT));
/*
Allocate the memory for the CIDA structure and it's variable length members. */ hGlobal = GlobalAlloc(GHND | GMEM_SHARE, (DWORD) (iCurPos + // size of the CIDA structure and the additional aoffset elements
(cbPidl + 1))); // size of the pidls
if (NULL == hGlobal) return (hGlobal);
pData = (LPIDA)GlobalLock(hGlobal);
if(pData) { pData->cidl = uItemCount + 1; pData->aoffset[0] = iCurPos;
//add the PIDL for the parent folder
cbPidl = pPidlMgr->GetSize(pidlParent); CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)pidlParent, cbPidl); iCurPos += cbPidl;
for(i = 0; i < uItemCount; i++) { //get the size of the PIDL
cbPidl = pPidlMgr->GetSize(aPidls[i]);
//fill out the members of the CIDA structure.
pData->aoffset[i + 1] = iCurPos;
//copy the contents of the PIDL
CopyMemory((LPBYTE)(pData) + iCurPos, (LPBYTE)aPidls[i], cbPidl);
//set up the position of the next PIDL
iCurPos += cbPidl; } GlobalUnlock(hGlobal); }
delete pPidlMgr;
return (hGlobal); }
/**************************************************************************
ItemDataDlgProc()
**************************************************************************/
BOOL CALLBACK ItemDataDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static LPTSTR pszData;
switch(uMsg) { case WM_INITDIALOG: pszData = (LPTSTR)lParam; if(IsBadWritePtr((LPVOID)pszData, MAX_DATA)) { EndDialog(hWnd, IDCANCEL); break; } SendDlgItemMessage(hWnd, IDC_DATA, EM_LIMITTEXT, MAX_DATA - 1, 0); SetDlgItemText(hWnd, IDC_DATA, pszData); break;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: EndDialog(hWnd, IDCANCEL); break;
case IDOK: GetDlgItemText(hWnd, IDC_DATA, pszData, MAX_DATA); EndDialog(hWnd, IDOK); break;
} break; default: break; }
return FALSE; }
/**************************************************************************
GetViewInterface()
**************************************************************************/
LPVOID GetViewInterface(HWND hWnd) { IUnknown *pRet = NULL;
if(IsViewWindow(hWnd)) { pRet = (IUnknown*)GetWindowLong(hWnd, VIEW_POINTER_OFFSET); }
if(pRet) pRet->AddRef();
return (LPVOID)pRet; }
/**************************************************************************
AddViewMenuItems()
**************************************************************************/
UINT AddViewMenuItems( HMENU hMenu, UINT uOffset, UINT uInsertBefore, BOOL fByPosition) { MENUITEMINFO mii; TCHAR szText[MAX_PATH] = TEXT(""); UINT uAdded = 0;
ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii);
//add the view menu items at the correct position in the menu
LoadString(g_hInst, IDS_VIEW_LARGE, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_VIEW_LARGE; InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
uAdded++;
LoadString(g_hInst, IDS_VIEW_SMALL, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_VIEW_SMALL; InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
uAdded++;
LoadString(g_hInst, IDS_VIEW_LIST, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_VIEW_LIST; InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
uAdded++;
LoadString(g_hInst, IDS_VIEW_DETAILS, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_VIEW_DETAILS; InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
uAdded++;
return uAdded; }
/**************************************************************************
AddFileMenuItems()
**************************************************************************/
UINT AddFileMenuItems( HMENU hMenu, UINT uOffset, UINT uInsertBefore, BOOL fByPosition) { //add the file menu items
TCHAR szText[MAX_PATH] = TEXT(""); MENUITEMINFO mii; HMENU hPopup; UINT uAdded = 0;
hPopup = CreatePopupMenu();
if(hPopup) { ZeroMemory(&mii, sizeof(mii)); mii.cbSize = sizeof(mii);
LoadString(g_hInst, IDS_NEW_FOLDER, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_NEW_FOLDER; InsertMenuItem(hPopup, -1, FALSE, &mii);
LoadString(g_hInst, IDS_NEW_ITEM, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_NEW_ITEM; InsertMenuItem(hPopup, -1, FALSE, &mii);
LoadString(g_hInst, IDS_NEW, szText, sizeof(szText)); mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU; mii.fType = MFT_STRING; mii.fState = MFS_ENABLED; mii.dwTypeData = szText; mii.wID = uOffset + IDM_NEW; mii.hSubMenu = hPopup; InsertMenuItem(hMenu, uInsertBefore, fByPosition, &mii);
uAdded++; }
return uAdded; }
|