www.pudn.com > 44w.rar > ListView.cpp
#include#include #include #include #include "listview.h" #include "resource.h" #include "AccessEnum.h" void InitListViewColumns( HWND hListView, const LISTVIEW_COLUMN * Cols, int numColumns, long style ) { HKEY hKey; DWORD valLength; TCHAR colName[32]; RECT rc; // Get window sizes rc.left = -1; rc.top = -1; RegCreateKey(HKEY_CURRENT_USER, _T("Software\\Sysinternals\\ShareEnum"), &hKey ); valLength = sizeof(DWORD); RegQueryValueEx( hKey, _T("x"), NULL, NULL, (LPBYTE) &rc.left, &valLength ); RegQueryValueEx( hKey, _T("y"), NULL, NULL, (LPBYTE) &rc.top, &valLength ); RegQueryValueEx( hKey, _T("w"), NULL, NULL, (LPBYTE) &rc.right, &valLength ); RegQueryValueEx( hKey, _T("h"), NULL, NULL, (LPBYTE) &rc.bottom, &valLength ); if( rc.left != -1 && rc.top != -1 ) MoveWindow( GetParent( hListView), rc.left, rc.top, rc.right, rc.bottom, TRUE ); // Set listview styles ListView_SetExtendedListViewStyleEx( hListView, style, style ); // Create columns for ( int i = 0; i < numColumns; ++i ) { LVCOLUMN col = { 0 }; col.mask = LVCF_TEXT | LVCF_WIDTH; col.pszText = (TCHAR *)Cols[i].Title; col.cx = Cols[i].Width; _stprintf( colName, _T("Column%d"), i ); valLength = sizeof(DWORD); RegQueryValueEx( hKey,colName, NULL, NULL, (LPBYTE) &col.cx, &valLength ); ListView_InsertColumn( hListView, i, &col ); } RegCloseKey( hKey ); HINSTANCE hInstance = GetModuleHandle(NULL); // Create image list (order corresponds to LISTVIEW_IMG_* enumeration) HIMAGELIST hImageList = ImageList_Create( GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLORDDB, 10, 30 ); UINT loadFlags = LR_DEFAULTCOLOR | LR_LOADTRANSPARENT | LR_SHARED; ImageList_SetBkColor( hImageList, GetSysColor(COLOR_BTNFACE) ); ImageList_AddIcon( hImageList, (HICON) LoadImage( hInstance, MAKEINTRESOURCE(IDI_DOWNARROW), IMAGE_ICON, 16, 16, loadFlags ) ); ImageList_AddIcon( hImageList, (HICON) LoadImage( hInstance, MAKEINTRESOURCE(IDI_UPARROW), IMAGE_ICON, 16, 16, loadFlags ) ); ImageList_SetBkColor( hImageList, GetSysColor(COLOR_WINDOW) ); ListView_SetImageList( hListView, hImageList, LVSIL_SMALL ); } void SaveListViewColumns( HWND hListView ) { HKEY hKey; DWORD valLength; TCHAR colName[32]; RECT rc; DWORD width; // Get window sizes GetWindowRect( GetParent( hListView), &rc ); rc.right -= rc.left; rc.bottom -= rc.top; RegCreateKey(HKEY_CURRENT_USER, _T("Software\\Sysinternals\\ShareEnum"), &hKey ); valLength = sizeof(DWORD); RegSetValueEx( hKey, _T("x"), NULL, REG_DWORD, (LPBYTE) &rc.left, sizeof( DWORD) ); RegSetValueEx( hKey, _T("y"), NULL, REG_DWORD, (LPBYTE) &rc.top, sizeof( DWORD) ); RegSetValueEx( hKey, _T("w"), NULL, REG_DWORD, (LPBYTE) &rc.right, sizeof( DWORD) ); RegSetValueEx( hKey, _T("h"), NULL, REG_DWORD, (LPBYTE) &rc.bottom, sizeof( DWORD) ); if( rc.left != -1 && rc.top != -1 ) SetWindowPos( GetParent( hListView), NULL, rc.left, rc.top, rc.right, rc.bottom, SWP_NOZORDER ); for ( int i = 0; i < 8; ++i ) { _stprintf( colName, _T("Column%d"), i ); width = ListView_GetColumnWidth( hListView, i ); RegSetValueEx( hKey,colName, NULL, REG_DWORD, (LPBYTE) &width, sizeof( DWORD)); } RegCloseKey( hKey ); } int FilenameCompare( const TCHAR * pa, const TCHAR * pb ) { int diff = CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH, pa, -1, pb, -1 ); if ( diff == CSTR_EQUAL ) diff = CompareString( LOCALE_USER_DEFAULT, SORT_STRINGSORT, pa, -1, pb, -1 ); return diff - CSTR_EQUAL; } int GetListViewSortColumn( LISTVIEW_COLUMN * ColumnList ) { for ( int i = 0; ColumnList[i].Title; ++i ) if ( ColumnList[i].SortDir != SORTDIR_UNDEF ) return i; return -1; } int CALLBACK CompareListViewColumn( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) { LISTVIEW_SORT * ctx = (LISTVIEW_SORT *) lParamSort; WCHAR text1[ MAX_UNCPATH ]; WCHAR text2[ MAX_UNCPATH ]; int order = CSTR_EQUAL; int idx1, idx2; LVFINDINFO find; double num1, num2; // Get indices of items if ( ctx->UsingEx ) { idx1 = lParam1; idx2 = lParam2; } else { find.flags = LVFI_PARAM; find.lParam = lParam1; idx1 = ListView_FindItem( ctx->hList, -1, &find ); find.lParam = lParam2; idx2 = ListView_FindItem( ctx->hList, -1, &find ); } ListView_GetItemText( ctx->hList, idx1, ctx->Column, text1, MAX_UNCPATH ); ListView_GetItemText( ctx->hList, idx2, ctx->Column, text2, MAX_UNCPATH ); switch ( ctx->ColumnList[ ctx->Column ].Type ) { case DATATYPE_TEXT: order = FilenameCompare( text1, text2 ); break; case DATATYPE_NUMBER: _stscanf( text1, TEXT("%lf"), &num1 ); _stscanf( text2, TEXT("%lf"), &num2 ); if ( num1 > num2 ) order = 1; else if ( num1 < num2 ) order = -1; else order = 0; break; case DATATYPE_HEX: _stscanf( text1, TEXT("%lx"), &num1 ); _stscanf( text2, TEXT("%lx"), &num2 ); if ( num1 > num2 ) order = 1; else if ( num1 < num2 ) order = -1; else order = 0; break; case DATATYPE_DATE: { VarDateFromStr( text1, LANG_USER_DEFAULT, 0, &num1 ); VarDateFromStr( text2, LANG_USER_DEFAULT, 0, &num2 ); if ( num1 < num2 ) order = -1; else if ( num1 > num2 ) order = 1; else order = 0; } break; } if ( ctx->ColumnList[ ctx->Column ].SortDir == SORTDIR_DOWN ) order = -order; return order; } void SortListView( HWND hListview, int iSubItem, LISTVIEW_COLUMN * ColumnList, bool Reverse ) { bool SortReversed = false; int PrevColumn = 0; // If column is negative then repeat the last sort if ( iSubItem < 0 ) { iSubItem = GetListViewSortColumn( ColumnList ); if ( iSubItem >= 0 ) SortListView( hListview, iSubItem, ColumnList, false ); return; } HCURSOR hSaveCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) ); // if sorting the same column twice in a row then reverse the sort order if ( ColumnList[ iSubItem ].SortDir == SORTDIR_UNDEF ) { // clicked on a new column for ( PrevColumn = 0; ColumnList[PrevColumn].Title; ++PrevColumn ) if ( ColumnList[PrevColumn].SortDir != SORTDIR_UNDEF ) break; ColumnList[PrevColumn].SortDir = SORTDIR_UNDEF; SortReversed = false; } else { // reverse sort direction if requested if ( Reverse ) SortReversed = ColumnList[ iSubItem ].SortDir == SORTDIR_UP; else SortReversed = ColumnList[ iSubItem ].SortDir != SORTDIR_UP; } ColumnList[ iSubItem ].SortDir = SortReversed ? SORTDIR_DOWN : SORTDIR_UP; // remove arrow from previously sorted column LVCOLUMN lvc; lvc.mask = LVCF_FMT; ListView_GetColumn( hListview, PrevColumn, &lvc ); lvc.fmt &= ~(LVCFMT_IMAGE | LVCFMT_COL_HAS_IMAGES | LVCFMT_BITMAP_ON_RIGHT); ListView_SetColumn( hListview, PrevColumn, &lvc ); // add arrow to sorted column lvc.mask = LVCF_FMT | LVCF_IMAGE; ListView_GetColumn( hListview, iSubItem, &lvc ); lvc.fmt |= LVCFMT_IMAGE | LVCFMT_COL_HAS_IMAGES | LVCFMT_BITMAP_ON_RIGHT; lvc.iImage = SortReversed ? LISTVIEW_IMG_DESCENDING : LISTVIEW_IMG_ASCENDING; ListView_SetColumn( hListview, iSubItem, &lvc ); // Perform sort LISTVIEW_SORT ctx; ctx.Column = iSubItem; ctx.ColumnList = ColumnList; ctx.hList = hListview; ctx.UsingEx = true; // Version 5.80 and later of Comctl32.dll BOOL ok = ListView_SortItemsEx( hListview, CompareListViewColumn, (LPARAM)&ctx ); if ( !ok ) { // Use old, slow way of sorting. ctx.UsingEx = false; ListView_SortItems( hListview, CompareListViewColumn, (LPARAM)&ctx ); } SetCursor( hSaveCursor ); } LPARAM ListView_GetParam( HWND hListView, UINT iItem ) { LV_ITEM lvi; lvi.mask = LVIF_PARAM; lvi.iItem = iItem; lvi.iSubItem = 0; if ( ! ListView_GetItem( hListView, &lvi ) ) lvi.lParam = (LPARAM) -1; return lvi.lParam; } void PopupListviewColumnsMenu( HWND hListview, LISTVIEW_COLUMN * ColumnList ) { HMENU hMenu = CreatePopupMenu(); MENUITEMINFO item; ZeroMemory(&item,sizeof(item)); // Build list of columns for (int col = 0; ColumnList[col].Title; ++col ) { item.cbSize = sizeof item; item.fMask = MIIM_ID | MIIM_STATE | MIIM_CHECKMARKS | MIIM_TYPE; item.wID = col + 1; // zero is used for errors or no selection item.fType = MFT_STRING; item.fState = ListView_GetColumnWidth( hListview, col ) ? MFS_CHECKED : 0; item.hbmpChecked = NULL; item.hbmpUnchecked = NULL; item.hbmpItem = HBMMENU_SYSTEM; item.dwTypeData = (TCHAR *) ColumnList[col].Title; InsertMenuItem( hMenu, col, true, &item ); } // add separator item.fType = MFT_SEPARATOR; InsertMenuItem( hMenu, col++, true, &item ); // add "more..." entry item.fType = MFT_STRING; item.fState = 0; item.dwTypeData = TEXT("More..."); item.wID = col + 1; // zero is used for errors or no selection InsertMenuItem( hMenu, col++, true, &item ); // create menu POINT pt; GetCursorPos( &pt ); int i = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, pt.x, pt.y, 0, hListview, NULL ); if ( i > 0 ) { // process result --i; if ( i >= col - 1 ) { MessageBox( hListview, TEXT("More"), NULL, MB_OK ); } else { if ( ListView_GetColumnWidth(hListview,i) > 0 ) { // delete item ColumnList[i].Width = ListView_GetColumnWidth( hListview, i ); ListView_SetColumnWidth( hListview, i, 0 ); #if 0 HWND hHeader = ListView_GetHeader( hListview ); Header_DeleteItem( hHeader, i ); #endif } else { // insert item ListView_SetColumnWidth( hListview, i, ColumnList[i].Width ); #if 0 HWND hHeader = ListView_GetHeader( hListview ); HDITEM item = { 0 }; item.mask = HDI_TEXT | HDI_WIDTH; item.pszText = (TCHAR *) ColumnList[i].Title; item.cxy = ColumnList[i].Width; Header_InsertItem( hHeader, i, &item ); #endif } } } }