📄 shlview.c
字号:
LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
bIsFolder1 = _ILIsFolder(pItemIdList1);
bIsFolder2 = _ILIsFolder(pItemIdList2);
bIsBothFolder = bIsFolder1 && bIsFolder2;
/* When sorting between a File and a Folder, the Folder gets sorted first */
if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
{
nDiff = bIsFolder1 ? -1 : 1;
}
else
{
/* Sort by Time: Folders or Files can be sorted */
if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
{
_ILGetFileDateTime(pItemIdList1, &fd1);
_ILGetFileDateTime(pItemIdList2, &fd2);
nDiff = CompareFileTime(&fd2, &fd1);
}
/* Sort by Attribute: Folder or Files can be sorted */
else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
{
_ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
_ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
/* Sort by FileName: Folder or Files can be sorted */
else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
{
/* Sort by Text */
_ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
_ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
/* Sort by File Size, Only valid for Files */
else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
{
nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
}
/* Sort by File Type, Only valid for Files */
else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
{
/* Sort by Type */
_ILGetFileType(pItemIdList1, strName1, MAX_PATH);
_ILGetFileType(pItemIdList2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
}
/* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
if(nDiff == 0)
{
_ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
_ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
nDiff = lstrcmpiA(strName1, strName2);
}
if(!pSortInfo->bIsAscending)
{
nDiff = -nDiff;
}
return nDiff;
}
/**********************************************************
* LV_FindItemByPidl()
*/
static int LV_FindItemByPidl(
IShellViewImpl * This,
LPCITEMIDLIST pidl)
{
LVITEMA lvItem;
lvItem.iSubItem = 0;
lvItem.mask = LVIF_PARAM;
for(lvItem.iItem = 0;
SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &lvItem);
lvItem.iItem++)
{
LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
{
return lvItem.iItem;
}
}
return -1;
}
/**********************************************************
* LV_AddItem()
*/
static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
{
LVITEMA lvItem;
TRACE("(%p)(pidl=%p)\n", This, pidl);
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
lvItem.iSubItem = 0;
lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
}
/**********************************************************
* LV_DeleteItem()
*/
static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
{
int nIndex;
TRACE("(%p)(pidl=%p)\n", This, pidl);
nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
}
/**********************************************************
* LV_RenameItem()
*/
static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
{
int nItem;
LVITEMA lvItem;
TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
if ( -1 != nItem )
{
lvItem.mask = LVIF_PARAM; /* only the pidl */
lvItem.iItem = nItem;
SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &lvItem);
SHFree((LPITEMIDLIST)lvItem.lParam);
lvItem.mask = LVIF_PARAM;
lvItem.iItem = nItem;
lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
SendMessageA(This->hWndList, LVM_SETITEMA, 0, (LPARAM) &lvItem);
SendMessageA(This->hWndList, LVM_UPDATE, nItem, 0);
return TRUE; /* FIXME: better handling */
}
return FALSE;
}
/**********************************************************
* ShellView_FillList()
*
* - gets the objectlist from the shellfolder
* - sorts the list
* - fills the list into the view
*/
static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
{
LPITEMIDLIST pidl = ptr;
IShellViewImpl *This = arg;
/* in a commdlg This works as a filemask*/
if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
SHFree(pidl);
return TRUE;
}
static HRESULT ShellView_FillList(IShellViewImpl * This)
{
LPENUMIDLIST pEnumIDList;
LPITEMIDLIST pidl;
DWORD dwFetched;
HRESULT hRes;
HDPA hdpa;
TRACE("%p\n",This);
/* get the itemlist from the shfolder*/
hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
if (hRes != S_OK)
{
if (hRes==S_FALSE)
return(NOERROR);
return(hRes);
}
/* create a pointer array */
hdpa = DPA_Create(16);
if (!hdpa)
{
return(E_OUTOFMEMORY);
}
/* copy the items into the array*/
while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
{
if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
{
SHFree(pidl);
}
}
/* sort the array */
DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
/*turn the listview's redrawing off*/
SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
DPA_DestroyCallback( hdpa, fill_list, This );
/*turn the listview's redrawing back on and force it to draw*/
SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
IEnumIDList_Release(pEnumIDList); /* destroy the list*/
return S_OK;
}
/**********************************************************
* ShellView_OnCreate()
*/
static LRESULT ShellView_OnCreate(IShellViewImpl * This)
{
IDropTarget* pdt;
SHChangeNotifyEntry ntreg;
IPersistFolder2 * ppf2 = NULL;
TRACE("%p\n",This);
if(ShellView_CreateList(This))
{
if(ShellView_InitList(This))
{
ShellView_FillList(This);
}
}
if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
{
RegisterDragDrop(This->hWnd, pdt);
IDropTarget_Release(pdt);
}
/* register for receiving notifications */
IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
if (ppf2)
{
IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
ntreg.fRecursive = TRUE;
This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
SHFree((LPITEMIDLIST)ntreg.pidl);
IPersistFolder2_Release(ppf2);
}
This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
return S_OK;
}
/**********************************************************
* #### Handling of the menus ####
*/
/**********************************************************
* ShellView_BuildFileMenu()
*/
static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
{ CHAR szText[MAX_PATH];
MENUITEMINFOA mii;
int nTools,i;
HMENU hSubMenu;
TRACE("(%p)\n",This);
hSubMenu = CreatePopupMenu();
if(hSubMenu)
{ /*get the number of items in our global array*/
for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
/*add the menu items*/
for(i = 0; i < nTools; i++)
{
LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
{
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.dwTypeData = szText;
mii.wID = Tools[i].idCommand;
}
else
{
mii.fType = MFT_SEPARATOR;
}
/* tack This item onto the end of the menu */
InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
}
}
TRACE("-- return (menu=%p)\n",hSubMenu);
return hSubMenu;
}
/**********************************************************
* ShellView_MergeFileMenu()
*/
static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
{ TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
if(hSubMenu)
{ /*insert This item at the beginning of the menu */
_InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
_InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
}
TRACE("--\n");
}
/**********************************************************
* ShellView_MergeViewMenu()
*/
static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
{
TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
if(hSubMenu)
{ /*add a separator at the correct position in the menu*/
MENUITEMINFOA mii;
static char view[] = "View";
_InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
mii.fType = MFT_STRING;
mii.dwTypeData = view;
mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
}
}
/**********************************************************
* ShellView_GetSelections()
*
* - fills the this->apidl list with the selected objects
*
* RETURNS
* number of selected items
*/
static UINT ShellView_GetSelections(IShellViewImpl * This)
{
LVITEMA lvItem;
UINT i = 0;
SHFree(This->apidl);
This->cidl = ListView_GetSelectedCount(This->hWndList);
This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
TRACE("selected=%i\n", This->cidl);
if(This->apidl)
{
TRACE("-- Items selected =%u\n", This->cidl);
lvItem.mask = LVIF_STATE | LVIF_PARAM;
lvItem.stateMask = LVIS_SELECTED;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
{
if(lvItem.state & LVIS_SELECTED)
{
This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
i++;
TRACE("-- selected Item found\n");
}
lvItem.iItem++;
}
}
return This->cidl;
}
/**********************************************************
* ShellView_OpenSelectedItems()
*/
static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
{
static UINT CF_IDLIST = 0;
HRESULT hr;
IDataObject* selection;
FORMATETC fetc;
STGMEDIUM stgm;
LPIDA pIDList;
LPCITEMIDLIST parent_pidl;
WCHAR parent_path[MAX_PATH];
LPCWSTR parent_dir = NULL;
SFGAOF attribs;
int i;
if (0 == ShellView_GetSelections(This))
{
return S_OK;
}
hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
(LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
0, (LPVOID *)&selection);
if (FAILED(hr))
return hr;
if (0 == CF_IDLIST)
{
CF_IDLIST = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
}
fetc.cfFormat = CF_IDLIST;
fetc.ptd = NULL;
fetc.dwAspect = DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.tymed = TYMED_HGLOBAL;
hr = IDataObject_QueryGetData(selection, &fetc);
if (FAILED(hr))
return hr;
hr = IDataObject_GetData(selection, &fetc, &stgm);
if (FAILED(hr))
return hr;
pIDList = GlobalLock(stgm.u.hGlobal);
parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
SHGetPathFromIDListW(parent_pidl, parent_path))
{
parent_dir = parent_path;
}
for (i = pIDList->cidl; i > 0; --i)
{
LPCITEMIDLIST pidl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -