static const columninfo RecycleBinColumns[] =
{
- {IDS_SHV_COLUMN1, &FMTID_Storage, PID_STG_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
+ {IDS_SHV_COLUMN_NAME, &FMTID_Storage, PID_STG_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
{IDS_SHV_COLUMN_DELFROM, &FMTID_Displaced, PID_DISPLACED_FROM, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
{IDS_SHV_COLUMN_DELDATE, &FMTID_Displaced, PID_DISPLACED_DATE, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
- {IDS_SHV_COLUMN2, &FMTID_Storage, PID_STG_SIZE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20},
- {IDS_SHV_COLUMN3, &FMTID_Storage, PID_STG_STORAGETYPE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
- {IDS_SHV_COLUMN4, &FMTID_Storage, PID_STG_WRITETIME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
+ {IDS_SHV_COLUMN_SIZE, &FMTID_Storage, PID_STG_SIZE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20},
+ {IDS_SHV_COLUMN_TYPE, &FMTID_Storage, PID_STG_STORAGETYPE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
+ {IDS_SHV_COLUMN_MODIFIED, &FMTID_Storage, PID_STG_WRITETIME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
/* {"creation time", &FMTID_Storage, PID_STG_CREATETIME, SHCOLSTATE_TYPE_DATE, LVCFMT_LEFT, 20}, */
/* {"attribs", &FMTID_Storage, PID_STG_ATTRIBUTES, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 20}, */
};
* Recycle Bin folder
*/
+HRESULT CRecyclerExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
+{
+ CComPtr<IDefaultExtractIconInit> initIcon;
+ HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ /* FIXME: This is completely unimplemented */
+ initIcon->SetNormalIcon(swShell32Name, 0);
+
+ return initIcon->QueryInterface(riid, ppvOut);
+}
+
class CRecycleBinEnum :
public CEnumIDListBase
{
BOOL bFound;
} SEARCH_CONTEXT, *PSEARCH_CONTEXT;
-typedef struct
-{
- DWORD dwNukeOnDelete;
- DWORD dwSerial;
- DWORD dwMaxCapacity;
-} DRIVE_ITEM_CONTEXT, *PDRIVE_ITEM_CONTEXT;
-
BOOL WINAPI CBSearchRecycleBin(IN PVOID Context, IN HANDLE hDeletedFile)
{
PSEARCH_CONTEXT pContext = (PSEARCH_CONTEXT)Context;
HRESULT WINAPI CRecycleBin::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
- return ShellObjectCreatorInit<CRecycleBinEnum>(dwFlags, IID_IEnumIDList, ppEnumIDList);
+ return ShellObjectCreatorInit<CRecycleBinEnum>(dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
}
HRESULT WINAPI CRecycleBin::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv)
HRESULT WINAPI CRecycleBin::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
- /* TODO */
- TRACE("(%p, %p, %p, %p)\n", this, (void *)lParam, pidl1, pidl2);
- if (pidl1->mkid.cb != pidl2->mkid.cb)
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, pidl1->mkid.cb - pidl2->mkid.cb);
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (unsigned short)memcmp(pidl1->mkid.abID, pidl2->mkid.abID, pidl1->mkid.cb));
+ PIDLRecycleStruct* pData1 = _ILGetRecycleStruct(pidl1);
+ PIDLRecycleStruct* pData2 = _ILGetRecycleStruct(pidl2);
+ LPWSTR pName1, pName2;
+
+ if(!pData1 || !pData2 || LOWORD(lParam) >= COLUMNS_COUNT)
+ return E_INVALIDARG;
+
+ SHORT result;
+ LONGLONG diff;
+ switch (LOWORD(lParam))
+ {
+ case 0: /* Name */
+ pName1 = PathFindFileNameW(pData1->szName);
+ pName2 = PathFindFileNameW(pData2->szName);
+ result = wcsicmp(pName1, pName2);
+ break;
+ case 1: /* Orig. Location */
+ result = wcsicmp(pData1->szName, pData2->szName);
+ break;
+ case 2: /* Date Deleted */
+ result = CompareFileTime(&pData1->DeletionTime, &pData2->DeletionTime);
+ break;
+ case 3: /* Size */
+ diff = pData1->FileSize.QuadPart - pData2->FileSize.QuadPart;
+ return MAKE_COMPARE_HRESULT(diff);
+ case 4: /* Type */
+ pName1 = PathFindExtensionW(pData1->szName);
+ pName2 = PathFindExtensionW(pData2->szName);
+ result = wcsicmp(pName1, pName2);
+ break;
+ case 5: /* Modified */
+ result = CompareFileTime(&pData1->LastModification, &pData2->LastModification);
+ break;
+ }
+ return MAKE_COMPARE_HRESULT(result);
}
HRESULT WINAPI CRecycleBin::CreateViewObject(HWND hwndOwner, REFIID riid, void **ppv)
}
else if (IsEqualIID (riid, IID_IShellView))
{
- hr = CDefView_Constructor(this, riid, ppv);
+ SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
+ hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppv);
}
else
return hr;
HRESULT WINAPI CRecycleBin::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
REFIID riid, UINT *prgfInOut, void **ppv)
{
- IUnknown *pObj = NULL;
+ LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(%p,%u,apidl=%p, %p %p)\n", this,
hr = QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
pObj = pDt;
}
- else if(IsEqualIID(riid, IID_IExtractIconA) && (cidl == 1))
+ else if((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1))
{
- // FIXME: This is not correct, it does not show the right icons
- LPITEMIDLIST pidlItem = ILCombine(pidl, apidl[0]);
- pObj = IExtractIconA_Constructor(pidlItem);
- SHFree(pidlItem);
- hr = S_OK;
- }
- else if (IsEqualIID(riid, IID_IExtractIconW) && (cidl == 1))
- {
- // FIXME: This is not correct, it does not show the right icons
- LPITEMIDLIST pidlItem = ILCombine(pidl, apidl[0]);
- pObj = IExtractIconW_Constructor(pidlItem);
- SHFree(pidlItem);
- hr = S_OK;
+ hr = CRecyclerExtractIcon_CreateInstance(apidl[0], riid, &pObj);
}
else
hr = E_NOINTERFACE;
TRACE("(%p, %p, %x, %p)\n", this, pidl, (unsigned int)uFlags, pName);
-
- if (_ILIsBitBucket (pidl))
- {
- WCHAR pszPath[100];
-
- if (HCR_GetClassNameW(CLSID_RecycleBin, pszPath, MAX_PATH))
- {
- pName->uType = STRRET_WSTR;
- pName->pOleStr = StrDupW(pszPath);
- return S_OK;
- }
- }
-
pFileDetails = _ILGetRecycleStruct(pidl);
if (!pFileDetails)
{
HRESULT WINAPI CRecycleBin::GetDefaultColumn(DWORD dwReserved, ULONG *pSort, ULONG *pDisplay)
{
TRACE("(%p, %x, %p, %p)\n", this, (unsigned int)dwReserved, pSort, pDisplay);
- *pSort = 0;
- *pDisplay = 0;
+ if (pSort)
+ *pSort = 0;
+ if (pDisplay)
+ *pDisplay = 0;
return S_OK;
}
pDetails->fmt = RecycleBinColumns[iColumn].fmt;
pDetails->cxChar = RecycleBinColumns[iColumn].cxChars;
if (pidl == NULL)
- {
- pDetails->str.uType = STRRET_WSTR;
- LoadStringW(shell32_hInstance, RecycleBinColumns[iColumn].column_name_id, buffer, MAX_PATH);
- return SHStrDupW(buffer, &pDetails->str.pOleStr);
- }
+ return SHSetStrRet(&pDetails->str, RecycleBinColumns[iColumn].column_name_id);
if (iColumn == COLUMN_NAME)
return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
FormatDateTime(buffer, MAX_PATH, &pFileDetails->LastModification);
break;
case COLUMN_TYPE:
+ // FIXME: We should in fact use a UNICODE version of _ILGetFileType
szTypeName[0] = L'\0';
wcscpy(buffer, PathFindExtensionW(pFileDetails->szName));
- if (!( HCR_MapTypeToValueW(buffer, buffer, sizeof(buffer) / sizeof(WCHAR), TRUE) &&
- HCR_MapTypeToValueW(buffer, szTypeName, sizeof(szTypeName) / sizeof(WCHAR), FALSE )))
+ if (!( HCR_MapTypeToValueW(buffer, buffer, _countof(buffer), TRUE) &&
+ HCR_MapTypeToValueW(buffer, szTypeName, _countof(szTypeName), FALSE )))
{
- wcscpy (szTypeName, PathFindExtensionW(pFileDetails->szName));
- wcscat(szTypeName, L"-");
- Length = wcslen(szTypeName);
- if (LoadStringW(shell32_hInstance, IDS_SHV_COLUMN1, &szTypeName[Length], (sizeof(szTypeName) / sizeof(WCHAR)) - Length))
- szTypeName[(sizeof(szTypeName)/sizeof(WCHAR))-1] = L'\0';
+ /* load localized file string */
+ szTypeName[0] = '\0';
+ if(LoadStringW(shell32_hInstance, IDS_ANY_FILE, szTypeName, _countof(szTypeName)))
+ {
+ szTypeName[63] = '\0';
+ StringCchPrintfW(buffer, _countof(buffer), szTypeName, PathFindExtensionW(pFileDetails->szName));
+ }
}
- pDetails->str.uType = STRRET_WSTR;
- return SHStrDupW(szTypeName, &pDetails->str.pOleStr);
- break;
+ return SHSetStrRet(&pDetails->str, szTypeName);
default:
return E_FAIL;
}
- pDetails->str.uType = STRRET_WSTR;
- return SHStrDupW(buffer, &pDetails->str.pOleStr);
+ return SHSetStrRet(&pDetails->str, buffer);
}
HRESULT WINAPI CRecycleBin::MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid)
return S_OK;
}
+BOOL CRecycleBin::RecycleBinIsEmpty()
+{
+ CComPtr<IEnumIDList> spEnumFiles;
+ HRESULT hr = EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &spEnumFiles);
+ if (FAILED(hr))
+ return TRUE;
+ CComHeapPtr<ITEMIDLIST> spPidl;
+ ULONG itemcount;
+ return spEnumFiles->Next(1, &spPidl, &itemcount) != S_OK;
+ }
+
/*************************************************************************
* RecycleBin IContextMenu interface
*/
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
- mii.fState = MFS_ENABLED;
+ mii.fState = RecycleBinIsEmpty() ? MFS_DISABLED : MFS_ENABLED;
szBuffer[0] = L'\0';
LoadStringW(shell32_hInstance, IDS_EMPTY_BITBUCKET, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
mii.dwTypeData = szBuffer;
return S_OK;
}
-void toggleNukeOnDeleteOption(HWND hwndDlg, BOOL bEnable)
-{
- if (bEnable)
- {
- SendDlgItemMessage(hwndDlg, 14001, BM_SETCHECK, BST_UNCHECKED, 0);
- EnableWindow(GetDlgItem(hwndDlg, 14002), FALSE);
- SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_CHECKED, 0);
- }
- else
- {
- SendDlgItemMessage(hwndDlg, 14001, BM_SETCHECK, BST_CHECKED, 0);
- EnableWindow(GetDlgItem(hwndDlg, 14002), TRUE);
- SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_UNCHECKED, 0);
- }
-}
-
-
-static VOID
-InitializeRecycleBinDlg(HWND hwndDlg, WCHAR DefaultDrive)
-{
- WCHAR CurDrive = L'A';
- WCHAR szDrive[] = L"A:\\";
- DWORD dwDrives;
- WCHAR szName[100];
- WCHAR szVolume[100];
- DWORD MaxComponent, Flags;
- DWORD dwSerial;
- LVCOLUMNW lc;
- HWND hDlgCtrl;
- LVITEMW li;
- INT itemCount;
- ULARGE_INTEGER TotalNumberOfFreeBytes, TotalNumberOfBytes, FreeBytesAvailable;
- RECT rect;
- int columnSize;
- int defIndex = 0;
- DWORD dwSize;
- PDRIVE_ITEM_CONTEXT pItem = NULL, pDefault = NULL, pFirst = NULL;
-
- hDlgCtrl = GetDlgItem(hwndDlg, 14000);
-
- if (!LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_LOCATION, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
- szVolume[0] = 0;
-
- GetClientRect(hDlgCtrl, &rect);
-
- memset(&lc, 0, sizeof(LV_COLUMN) );
- lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
-
- columnSize = 140; //FIXME
- lc.iSubItem = 0;
- lc.fmt = LVCFMT_FIXED_WIDTH;
- lc.cx = columnSize;
- lc.cchTextMax = wcslen(szVolume);
- lc.pszText = szVolume;
- (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&lc);
-
- if (!LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_DISKSPACE, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
- szVolume[0] = 0;
-
- lc.iSubItem = 1;
- lc.cx = rect.right - rect.left - columnSize;
- lc.cchTextMax = wcslen(szVolume);
- lc.pszText = szVolume;
- (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM)&lc);
-
- dwDrives = GetLogicalDrives();
- itemCount = 0;
- do
- {
- if ((dwDrives & 0x1))
- {
- UINT Type = GetDriveTypeW(szDrive);
- if (Type == DRIVE_FIXED) //FIXME
- {
- if (!GetVolumeInformationW(szDrive, szName, sizeof(szName) / sizeof(WCHAR), &dwSerial, &MaxComponent, &Flags, NULL, 0))
- {
- szName[0] = 0;
- dwSerial = -1;
- }
-
- swprintf(szVolume, L"%s (%c:)", szName, szDrive[0]);
- memset(&li, 0x0, sizeof(LVITEMW));
- li.mask = LVIF_TEXT | LVIF_PARAM;
- li.iSubItem = 0;
- li.pszText = szVolume;
- li.iItem = itemCount;
- SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
- if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailable , &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
- {
- if (StrFormatByteSizeW(TotalNumberOfFreeBytes.QuadPart, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
- {
-
- pItem = (DRIVE_ITEM_CONTEXT *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DRIVE_ITEM_CONTEXT));
- if (pItem)
- {
- swprintf(szName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\%04X-%04X", LOWORD(dwSerial), HIWORD(dwSerial));
- dwSize = sizeof(DWORD);
- RegGetValueW(HKEY_CURRENT_USER, szName, L"MaxCapacity", RRF_RT_DWORD, NULL, &pItem->dwMaxCapacity, &dwSize);
- dwSize = sizeof(DWORD);
- RegGetValueW(HKEY_CURRENT_USER, szName, L"NukeOnDelete", RRF_RT_DWORD, NULL, &pItem->dwNukeOnDelete, &dwSize);
- pItem->dwSerial = dwSerial;
- li.mask = LVIF_PARAM;
- li.lParam = (LPARAM)pItem;
- (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
- if (CurDrive == DefaultDrive)
- {
- defIndex = itemCount;
- pDefault = pItem;
- }
- }
- if (!pFirst)
- pFirst = pItem;
-
- li.mask = LVIF_TEXT;
- li.iSubItem = 1;
- li.pszText = szVolume;
- li.iItem = itemCount;
- (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
- }
- }
- itemCount++;
- }
- }
- CurDrive++;
- szDrive[0] = CurDrive;
- dwDrives = (dwDrives >> 1);
- } while(dwDrives);
-
- if (!pDefault)
- pDefault = pFirst;
- if (pDefault)
- {
- toggleNukeOnDeleteOption(hwndDlg, pDefault->dwNukeOnDelete);
- SetDlgItemInt(hwndDlg, 14002, pDefault->dwMaxCapacity, FALSE);
- }
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_STATE;
- li.stateMask = (UINT) - 1;
- li.state = LVIS_FOCUSED | LVIS_SELECTED;
- li.iItem = defIndex;
- (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
-
-}
-
-static BOOL StoreDriveSettings(HWND hwndDlg)
-{
- int iCount, iIndex;
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14000);
- LVITEMW li;
- PDRIVE_ITEM_CONTEXT pItem;
- HKEY hKey, hSubKey;
- WCHAR szSerial[20];
- DWORD dwSize;
-
-
- if (RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
- return FALSE;
-
- iCount = ListView_GetItemCount(hDlgCtrl);
-
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_PARAM;
-
- for(iIndex = 0; iIndex < iCount; iIndex++)
- {
- li.iItem = iIndex;
- if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
- {
- pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
- swprintf(szSerial, L"%04X-%04X", LOWORD(pItem->dwSerial), HIWORD(pItem->dwSerial));
- if (RegCreateKeyExW(hKey, szSerial, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
- {
- dwSize = sizeof(DWORD);
- RegSetValueExW(hSubKey, L"NukeOnDelete", 0, REG_DWORD, (LPBYTE)&pItem->dwNukeOnDelete, dwSize);
- dwSize = sizeof(DWORD);
- RegSetValueExW(hSubKey, L"MaxCapacity", 0, REG_DWORD, (LPBYTE)&pItem->dwMaxCapacity, dwSize);
- RegCloseKey(hSubKey);
- }
- }
- }
- RegCloseKey(hKey);
- return TRUE;
-
-}
-
-static VOID FreeDriveItemContext(HWND hwndDlg)
-{
- int iCount, iIndex;
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14000);
- LVITEMW li;
-
- iCount = ListView_GetItemCount(hDlgCtrl);
-
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_PARAM;
-
- for(iIndex = 0; iIndex < iCount; iIndex++)
- {
- li.iItem = iIndex;
- if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
- {
- HeapFree(GetProcessHeap(), 0, (LPVOID)li.lParam);
- }
- }
-}
-
-static INT
-GetDefaultItem(HWND hwndDlg, LVITEMW * li)
-{
- HWND hDlgCtrl;
- UINT iItemCount, iIndex;
-
- hDlgCtrl = GetDlgItem(hwndDlg, 14000);
- if (!hDlgCtrl)
- return -1;
-
- iItemCount = ListView_GetItemCount(hDlgCtrl);
- if (!iItemCount)
- return -1;
-
- ZeroMemory(li, sizeof(LVITEMW));
- li->mask = LVIF_PARAM | LVIF_STATE;
- li->stateMask = (UINT) - 1;
- for (iIndex = 0; iIndex < iItemCount; iIndex++)
- {
- li->iItem = iIndex;
- if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)li))
- {
- if (li->state & LVIS_SELECTED)
- return iIndex;
- }
- }
- return -1;
-
-}
-
-static INT_PTR CALLBACK
-RecycleBinDlg(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- LPPSHNOTIFY lppsn;
- LPNMLISTVIEW lppl;
- LVITEMW li;
- PDRIVE_ITEM_CONTEXT pItem;
- BOOL bSuccess;
- UINT uResult;
- PROPSHEETPAGE * page;
- DWORD dwStyle;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
- page = (PROPSHEETPAGE*)lParam;
- InitializeRecycleBinDlg(hwndDlg, (WCHAR)page->lParam);
- dwStyle = (DWORD) SendDlgItemMessage(hwndDlg, 14000, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
- dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
- SendDlgItemMessage(hwndDlg, 14000, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
- if (GetDlgCtrlID((HWND)wParam) != 14000)
- {
- SetFocus(GetDlgItem(hwndDlg, 14000));
- return FALSE;
- }
- return TRUE;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case 14001:
- toggleNukeOnDeleteOption(hwndDlg, FALSE);
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
- break;
- case 14003:
- toggleNukeOnDeleteOption(hwndDlg, TRUE);
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
- break;
- case 14004:
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
- break;
- }
- break;
- case WM_NOTIFY:
- lppsn = (LPPSHNOTIFY) lParam;
- lppl = (LPNMLISTVIEW) lParam;
- if (lppsn->hdr.code == PSN_APPLY)
- {
- if (GetDefaultItem(hwndDlg, &li) > -1)
- {
- pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
- if (pItem)
- {
- uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE);
- if (bSuccess)
- pItem->dwMaxCapacity = uResult;
- if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
- pItem->dwNukeOnDelete = TRUE;
- else
- pItem->dwNukeOnDelete = FALSE;
- }
- }
- if (StoreDriveSettings(hwndDlg))
- {
- SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
- return TRUE;
- }
- }
- else if (lppl->hdr.code == LVN_ITEMCHANGING)
- {
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_PARAM;
- li.iItem = lppl->iItem;
- if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&li))
- return TRUE;
-
- pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
- if (!pItem)
- return TRUE;
-
- if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
- {
- /* new focused item */
- toggleNukeOnDeleteOption(lppl->hdr.hwndFrom, pItem->dwNukeOnDelete);
- SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE);
- }
- else if ((lppl->uOldState & LVIS_FOCUSED) && !(lppl->uNewState & LVIS_FOCUSED))
- {
- /* kill focus */
- uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE);
- if (bSuccess)
- pItem->dwMaxCapacity = uResult;
- if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
- pItem->dwNukeOnDelete = TRUE;
- else
- pItem->dwNukeOnDelete = FALSE;
- }
- return TRUE;
-
- }
- break;
- case WM_DESTROY:
- FreeDriveItemContext(hwndDlg);
- break;
- }
- return FALSE;
-}
-
-BOOL SH_ShowRecycleBinProperties(WCHAR sDrive)
-{
- HPROPSHEETPAGE hpsp[1];
- PROPSHEETHEADERW psh;
- HPROPSHEETPAGE hprop;
-
- BOOL ret;
-
-
- ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
- psh.dwSize = sizeof(PROPSHEETHEADERW);
- psh.dwFlags = PSP_DEFAULT | PSH_PROPTITLE;
- psh.pszCaption = MAKEINTRESOURCEW(IDS_RECYCLEBIN_FOLDER_NAME);
- psh.hwndParent = NULL;
- psh.phpage = hpsp;
- psh.hInstance = shell32_hInstance;
-
- hprop = SH_CreatePropertySheetPage(IDD_RECYCLE_BIN_PROPERTIES, RecycleBinDlg, (LPARAM)sDrive, NULL);
- if (!hprop)
- {
- ERR("Failed to create property sheet\n");
- return FALSE;
- }
- hpsp[psh.nPages] = hprop;
- psh.nPages++;
-
-
- ret = PropertySheetW(&psh);
- if (ret < 0)
- return FALSE;
- else
- return TRUE;
-}
-
BOOL
TRASH_CanTrashFile(LPCWSTR wszPath)
{
InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
/* Handle cfShellIDList Drop objects here, otherwise send the approriate message to other software */
- if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) {
- IStream *s;
- CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pDataObject, &s);
- SHCreateThread(DoDeleteThreadProc, s, NULL, NULL);
+ if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
+ {
+ DWORD fMask = 0;
+
+ if ((dwKeyState & MK_SHIFT) == MK_SHIFT)
+ fMask |= CMIC_MASK_SHIFT_DOWN;
+
+ DoDeleteAsync(pDataObject, fMask);
}
else
{
return S_OK;
}
-DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter)
-{
- CoInitialize(NULL);
- CComPtr<IDataObject> pDataObject;
- HRESULT hr = CoGetInterfaceAndReleaseStream (static_cast<IStream*>(lpParameter), IID_PPV_ARG(IDataObject, &pDataObject));
- if (SUCCEEDED(hr))
- {
- DoDeleteDataObject(pDataObject);
- }
- CoUninitialize();
- return 0;
-}
-
-HRESULT WINAPI DoDeleteDataObject(IDataObject *pda)
+HRESULT WINAPI DoDeleteDataObject(IDataObject *pda, DWORD fMask)
{
- TRACE("performing delete");
HRESULT hr;
-
STGMEDIUM medium;
FORMATETC formatetc;
- InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
+ InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
hr = pda->GetData(&formatetc, &medium);
- if (FAILED(hr))
+ if (FAILED_UNEXPECTEDLY(hr))
return hr;
- /* lock the handle */
- LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
- if (!lpcida)
+ LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
+ if (!lpdf)
{
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* convert the data into pidl */
- LPITEMIDLIST pidl;
- LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
- if (!apidl)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- CComPtr<IShellFolder> psfDesktop;
- CComPtr<IShellFolder> psfFrom = NULL;
-
- /* Grab the desktop shell folder */
- hr = SHGetDesktopFolder(&psfDesktop);
- if (FAILED(hr))
- {
- ERR("SHGetDesktopFolder failed\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* Find source folder, this is where the clipboard data was copied from */
- if (_ILIsDesktop(pidl))
- {
- psfFrom = psfDesktop;
- }
- else
- {
- hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
- if (FAILED(hr))
- {
- ERR("no IShellFolder\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
- }
-
- STRRET strTemp;
- hr = psfFrom->GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strTemp);
- if (FAILED(hr))
- {
- ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return hr;
- }
-
- WCHAR wszPath[MAX_PATH];
- hr = StrRetToBufW(&strTemp, apidl[0], wszPath, _countof(wszPath));
- if (FAILED(hr))
- {
- ERR("StrRetToBufW failed with %x\n", hr);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return hr;
- }
-
- /* Only keep the base path */
- LPWSTR pwszFilename = PathFindFileNameW(wszPath);
- *pwszFilename = L'\0';
-
- /* Build paths list */
- LPWSTR pwszPaths = BuildPathsList(wszPath, lpcida->cidl, (LPCITEMIDLIST*) apidl);
- if (!pwszPaths)
- {
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
+ ERR("Error locking global\n");
return E_FAIL;
}
SHFILEOPSTRUCTW FileOp;
ZeroMemory(&FileOp, sizeof(FileOp));
FileOp.wFunc = FO_DELETE;
- FileOp.pFrom = pwszPaths;
- FileOp.fFlags = FOF_ALLOWUNDO;
+ FileOp.pFrom = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);;
+ if ((fMask & CMIC_MASK_SHIFT_DOWN) == 0)
+ FileOp.fFlags = FOF_ALLOWUNDO;
if (SHFileOperationW(&FileOp) != 0)
{
- ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(pwszPaths));
+ ERR("SHFileOperation failed with 0x%x\n", GetLastError());
hr = E_FAIL;
}
- HeapFree(GetProcessHeap(), 0, pwszPaths);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
ReleaseStgMedium(&medium);
return hr;
}
+struct DeleteThreadData {
+ IStream *s;
+ DWORD fMask;
+};
+
+DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter)
+{
+ DeleteThreadData *data = static_cast<DeleteThreadData*>(lpParameter);
+ CoInitialize(NULL);
+ IDataObject *pDataObject;
+ HRESULT hr = CoGetInterfaceAndReleaseStream (data->s, IID_PPV_ARG(IDataObject, &pDataObject));
+ if (SUCCEEDED(hr))
+ {
+ DoDeleteDataObject(pDataObject, data->fMask);
+ }
+ pDataObject->Release();
+ CoUninitialize();
+ HeapFree(GetProcessHeap(), 0, data);
+ return 0;
+}
+
+void DoDeleteAsync(IDataObject *pda, DWORD fMask)
+{
+ DeleteThreadData *data = static_cast<DeleteThreadData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(DeleteThreadData)));
+ data->fMask = fMask;
+ CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pda, &data->s);
+ SHCreateThread(DoDeleteThreadProc, data, NULL, NULL);
+}
+
/*************************************************************************
* SHEmptyRecycleBinA (SHELL32.@)
*/