- implemented sorting the listview by clicking on the column header

- implemented the context menu entrys for sorting
- some more functions to gather data form pidls
oldstable
Juergen Schmied 1999-10-13 15:53:05 +00:00 committed by Alexandre Julliard
parent 3c216d01eb
commit e340c707ba
6 changed files with 310 additions and 37 deletions

View File

@ -6203,6 +6203,25 @@ static LRESULT LISTVIEW_Notify(HWND hwnd, INT nCtrlId, LPNMHDR lpnmh)
infoPtr->nItemWidth = LISTVIEW_GetItemWidth(hwnd);
InvalidateRect(hwnd, NULL, TRUE);
}
if(lpnmh->code == HDN_ITEMCLICKA)
{
/* Handle sorting by Header Column */
NMLISTVIEW nmlv;
LPNMHEADERA pnmHeader = (LPNMHEADERA) lpnmh;
LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
nmlv.hdr.hwndFrom = hwnd;
nmlv.hdr.idFrom = lCtrlId;
nmlv.hdr.code = LVN_COLUMNCLICK;
nmlv.iItem = -1;
nmlv.iSubItem = pnmHeader->iItem;
ListView_LVNotify(GetParent(hwnd),lCtrlId, &nmlv);
InvalidateRect(hwnd, NULL, TRUE);
}
}
return 0;

View File

@ -19,6 +19,7 @@
#include "winnls.h"
#include "winversion.h"
#include "shell32_main.h"
#include "shellapi.h"
#include "pidl.h"
#include "wine/undocshell.h"
@ -1512,36 +1513,79 @@ REFIID WINAPI _ILGetGUIDPointer(LPCITEMIDLIST pidl)
return NULL;
}
/*************************************************************************
* _ILGetFileDateTime
*
* Given the ItemIdList, get the FileTime
*
* PARAMS
* pidl [I] The ItemIDList
* pFt [I] the resulted FILETIME of the file
*
* RETURNS
* True if Successful
*
* NOTES
*
*/
BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *pFt)
{
LPPIDLDATA pdata =_ILGetDataPointer(pidl);
switch (pdata->type)
{
case PT_FOLDER:
DosDateTimeToFileTime(pdata->u.folder.uFileDate, pdata->u.folder.uFileTime, pFt);
break;
case PT_VALUE:
DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt);
break;
default:
return FALSE;
}
return TRUE;
}
BOOL WINAPI _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{ LPPIDLDATA pdata =_ILGetDataPointer(pidl);
{
FILETIME ft;
SYSTEMTIME time;
switch (pdata->type)
{ case PT_FOLDER:
DosDateTimeToFileTime(pdata->u.folder.uFileDate, pdata->u.folder.uFileTime, &ft);
break;
case PT_VALUE:
DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, &ft);
break;
default:
return FALSE;
}
if (! _ILGetFileDateTime( pidl, &ft )) return FALSE;
FileTimeToSystemTime (&ft, &time);
return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, pOut, uOutSize);
}
BOOL WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{ LPPIDLDATA pdata =_ILGetDataPointer(pidl);
/*************************************************************************
* _ILGetFileSize
*
* Given the ItemIdList, get the FileSize
*
* PARAMS
* pidl [I] The ItemIDList
* pOut [I] The buffer to save the result
* uOutsize [I] The size of the buffer
*
* RETURNS
* The FileSize
*
* NOTES
* pOut can be null when no string is needed
*
*/
DWORD WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
LPPIDLDATA pdata =_ILGetDataPointer(pidl);
DWORD dwSize;
switch (pdata->type)
{ case PT_VALUE:
break;
default:
return FALSE;
dwSize = pdata->u.file.dwFileSize;
if (pOut) StrFormatByteSizeA(dwSize, pOut, uOutSize);
return dwSize;
}
StrFormatByteSizeA(pdata->u.file.dwFileSize, pOut, uOutSize);
return TRUE;
return 0;
}
BOOL WINAPI _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
@ -1570,3 +1614,103 @@ BOOL WINAPI _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
return TRUE;
}
/*************************************************************************
* _ILGetFileType
*
* Given the ItemIdList, get the file type description
*
* PARAMS
* pidl [I] The ItemIDList (simple)
* pOut [I] The buffer to save the result
* uOutsize [I] The size of the buffer
*
* RETURNS
* nothing
*
* NOTES
* This function copies as much as possible into the buffer.
*/
void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
if(_ILIsValue(pidl))
{
char sTemp[64];
if (_ILGetExtension (pidl, sTemp, 64))
{
if (!( HCR_MapTypeToValue(sTemp, sTemp, 64, TRUE)
&& HCR_MapTypeToValue(sTemp, pOut, uOutSize, FALSE )))
{
lstrcpynA (pOut, sTemp, uOutSize - 6);
strcat (pOut, "-file");
}
}
}
else
{
lstrcpynA(pOut, "Folder", uOutSize);
}
}
/*************************************************************************
* _ILGetAttributeStr
*
* Given the ItemIdList, get the Attrib string format
*
* PARAMS
* pidl [I] The ItemIDList
* pOut [I] The buffer to save the result
* uOutsize [I] The size of the Buffer
*
* RETURNS
* True if successful
*
* NOTES
*
*/
BOOL _ILGetAttributeStr(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
{
LPPIDLDATA pData =_ILGetDataPointer(pidl);
WORD wAttrib;
int i;
/* Need At Least 6 characters to represent the Attrib String */
if(uOutSize < 6)
{
return FALSE;
}
switch(pData->type)
{
case PT_FOLDER:
wAttrib = pData->u.folder.uFileAttribs;
break;
case PT_VALUE:
wAttrib = pData->u.file.uFileAttribs;
break;
default:
return FALSE;
}
i=0;
if(wAttrib & FILE_ATTRIBUTE_READONLY)
{
pOut[i++] = 'R';
}
if(wAttrib & FILE_ATTRIBUTE_HIDDEN)
{
pOut[i++] = 'H';
}
if(wAttrib & FILE_ATTRIBUTE_SYSTEM)
{
pOut[i++] = 'S';
}
if(wAttrib & FILE_ATTRIBUTE_ARCHIVE)
{
pOut[i++] = 'A';
}
if(wAttrib & FILE_ATTRIBUTE_COMPRESSED)
{
pOut[i++] = 'C';
}
pOut[i] = 0x00;
return TRUE;
}

View File

@ -124,7 +124,7 @@ DWORD WINAPI _ILGetDrive(LPCITEMIDLIST,LPSTR,UINT16);
* getting special values from simple pidls
*/
BOOL WINAPI _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
BOOL WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
BOOL WINAPI _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
@ -168,4 +168,12 @@ REFIID WINAPI _ILGetGUIDPointer(LPCITEMIDLIST pidl);
void pdump (LPCITEMIDLIST pidl);
BOOL pcheck (LPCITEMIDLIST pidl);
/*
* ItemIDList File helper functions
*/
void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *ft);
BOOL _ILGetAttributeStr(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
#endif

View File

@ -170,23 +170,7 @@ DWORD WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes,
/* get the type name */
if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME))
{
if(_ILIsValue(pidlLast))
{
char sTemp[64];
if (_ILGetExtension (pidlLast, sTemp, 64))
{
if (!( HCR_MapTypeToValue(sTemp, sTemp, 64, TRUE)
&& HCR_MapTypeToValue(sTemp, psfi->szTypeName, 80, FALSE )))
{
lstrcpynA (psfi->szTypeName, sTemp, 74);
strcat (psfi->szTypeName, "-file");
}
}
}
else
{
strcpy(psfi->szTypeName, "Folder");
}
_ILGetFileType(pidlLast, psfi->szTypeName, 80);
}
/* ### icons ###*/

View File

@ -71,6 +71,13 @@ static struct ICOM_VTABLE(IViewObject) vovt;
#define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
#define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
/* ListView Header ID's */
#define LISTVIEW_COLUMN_NAME 0
#define LISTVIEW_COLUMN_SIZE 1
#define LISTVIEW_COLUMN_TYPE 2
#define LISTVIEW_COLUMN_TIME 3
#define LISTVIEW_COLUMN_ATTRIB 4
/*menu items */
#define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
#define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
@ -314,6 +321,96 @@ static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARA
return ret;
}
/*************************************************************************
* ShellView_ListViewCompareItems
*
* Compare Function for the Listview (FileOpen Dialog)
*
* PARAMS
* lParam1 [I] the first ItemIdList to compare with
* lParam2 [I] the second ItemIdList to compare with
* lpData [I] The column ID for the header Ctrl to process
*
* RETURNS
* A negative value if the first item should precede the second,
* a positive value if the first item should follow the second,
* or zero if the two items are equivalent
*
* NOTES
*
*/
static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
{
INT nDiff=0;
FILETIME fd1, fd2;
char strName1[MAX_PATH], strName2[MAX_PATH];
BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
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(lpData == LISTVIEW_COLUMN_TIME)
{
_ILGetFileDateTime(pItemIdList1, &fd1);
_ILGetFileDateTime(pItemIdList2, &fd2);
nDiff = CompareFileTime(&fd2, &fd1);
}
/* Sort by Attribute: Folder or Files can be sorted */
else if(lpData == LISTVIEW_COLUMN_ATTRIB)
{
_ILGetAttributeStr(pItemIdList1, strName1, MAX_PATH);
_ILGetAttributeStr(pItemIdList2, strName2, MAX_PATH);
nDiff = strcasecmp(strName1, strName2);
}
/* Sort by FileName: Folder or Files can be sorted */
else if(lpData == LISTVIEW_COLUMN_NAME || bIsBothFolder)
{
/* Sort by Text */
_ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
_ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
nDiff = strcasecmp(strName1, strName2);
}
/* Sort by File Size, Only valid for Files */
else if(lpData == LISTVIEW_COLUMN_SIZE)
{
nDiff = _ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0);
}
/* Sort by File Type, Only valid for Files */
else if(lpData == LISTVIEW_COLUMN_TYPE)
{
/* Sort by Type */
_ILGetFileType(pItemIdList1, strName1, MAX_PATH);
_ILGetFileType(pItemIdList2, strName2, MAX_PATH);
nDiff = strcasecmp(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 = strcasecmp(strName1, strName2);
}
return nDiff;
}
/**********************************************************
* ShellView_FillList()
*
@ -812,6 +909,9 @@ static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
/**********************************************************
* ShellView_OnCommand()
*
* NOTES
* the CmdID's are the ones from the context menu
*/
static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
{
@ -839,6 +939,14 @@ static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dw
SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
break;
/* the menu-ID's for sorting are 0x30... see shrec.rc */
case 0x30:
case 0x31:
case 0x32:
case 0x33:
ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (dwCmdID - 0x30));
break;
default:
TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
}
@ -850,7 +958,7 @@ static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dw
*/
static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
{ NM_LISTVIEW *lpnmlv = (NM_LISTVIEW*)lpnmh;
{ LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
LPITEMIDLIST pidl;
STRRET str;
@ -888,6 +996,12 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn
ShellView_DoContextMenu(This, 0, 0, TRUE);
break;
case LVN_COLUMNCLICK:
{
ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (lpnmlv->iSubItem));
break;
}
case LVN_GETDISPINFOA:
TRACE("-- LVN_GETDISPINFOA %p\n",This);
pidl = (LPITEMIDLIST)lpdi->item.lParam;

View File

@ -203,6 +203,10 @@ static HRESULT WINAPI ISVBgCm_fnInvokeCommand(
case FCIDM_SHVIEW_REPORTVIEW:
SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW,0),0 );
break;
default:
SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 );
break;
}
}