LONG TreeListInsertColumn( __in PTREELIST_OBJECT Object, __in LONG Column, __in LONG Align, __in LONG Width, __in PWSTR Title ) { HDITEM hdi = {0}; hdi.mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT | HDI_LPARAM; hdi.cxy = Width; hdi.fmt = Align; hdi.pszText = Title; hdi.cchTextMax = MAX_PATH; hdi.lParam = (LPARAM)&Object->Column[Column]; Object->Column[Column].Align = Align; Object->Column[Column].Width = Width; wcscpy_s(Object->Column[Column].Name, MAX_HEADER_NAME, Title); Header_InsertItem(Object->hWndHeader, Column, &hdi); Object->ColumnCount += 1; TreeListUpdateColumn(Object); return Column; }
BOOL AdjustClbHeadings( IN HWND hWnd, IN LPCLB_INFO ClbInfo, IN LPCWSTR Headings OPTIONAL ) /*++ Routine Description: AdjustClbHeadings adjust the number of columns, the widths an header text bbased on the optional Headings parameter. If Headings is NULL then the column widths are adjusted based on the old headings and the current size of the Clb. If Headings are supplied then they consist of ';' separated strings, each of which is a column heading. The number of columns and their widths is then computed based on these new headings. Arguments: hWnd - Supplies a window handle for this Clb. ClbInfo - Supplies a pointer the CLB_INFO structure for this Clb. Headings - Supplies an optional pointer to a ';' separated series of column header strings. Return Value: BOOL - Returns TRUE if the adjustment was succesfully made. --*/ { BOOL Success; DWORD Columns; DWORD ColumnWidth; DWORD i; TCHAR Buffer[ MAX_PATH ]; LPCWSTR Heading; RECT ClientRectHeader; HD_ITEM hdi; UINT iCount, j, iRight; DbgPointerAssert( ClbInfo ); DbgAssert( ! (( ClbInfo->Columns == 0 ) && ( Headings == NULL ))); // // If the user supplied headings, compute the new number of columns. // if( ARGUMENT_PRESENT( Headings )) { // // Initialize the column counter. // Columns = 0; // // Make a copy of the new headings in the Clb object. // lstrcpy( ClbInfo->Headings, Headings ); // // Make a copy of the heading string so that it can be tokenized. // i.e. wcstok destroys the string. // lstrcpy( Buffer, Headings ); // // Grab the first token (heading). // Heading = _tcstok( Buffer, HEADING_SEPARATOR ); // // For each heading... // while( Heading != NULL ) { // // Increment the number of columns. // Columns++; // // Get the next heading. // Heading = _tcstok( NULL, HEADING_SEPARATOR ); } } else { // // Same number of Columns as before. // Columns = ClbInfo->Columns; } // // If the number of columns in the Clb is zero (i.e. this is the first // time it is being initialized) allocate the right edge array. Otherwise // reallocate the existing array if the number of columns has changed. // if( ClbInfo->Columns == 0 ) { ClbInfo->Right = AllocateObject( LONG, Columns ); DbgPointerAssert( ClbInfo->Right ); } else if( Columns != ClbInfo->Columns ) { ClbInfo->Right = ReallocateObject( LONG, ClbInfo->Right, Columns ); DbgPointerAssert( ClbInfo->Right ); } // // Update the number of columns in the Clb (note this may be the same // number as before). // ClbInfo->Columns = Columns; // // Compute the default column width by dividing the available space by the // number of columns. // Success = GetClientRect( ClbInfo->hWndHeader, &ClientRectHeader ); DbgAssert( Success ); ColumnWidth = ( ClientRectHeader.right - ClientRectHeader.left ) / ClbInfo->Columns; // // Initialize the array of right edges to the width of each column. // for( i = 0; i < ClbInfo->Columns; i++ ) { ClbInfo->Right[ i ] = ColumnWidth; } // // Update the existing header items // iCount = Header_GetItemCount(ClbInfo->hWndHeader); j = 0; hdi.mask = HDI_WIDTH; while ((j < iCount) && (j < Columns)) { hdi.cxy = ClbInfo->Right[j]; Header_SetItem (ClbInfo->hWndHeader, j, &hdi); j++; } // // Add new header items if necessary. // hdi.mask = HDI_WIDTH; for (; j < Columns; j++) { hdi.cxy = ClbInfo->Right[j]; Header_InsertItem (ClbInfo->hWndHeader, j, &hdi); } // // Query the header for the array of right edges. // iRight = 0; for( i = 0; i < ClbInfo->Columns - 1; i++ ) { iRight += ClbInfo->Right[i]; ClbInfo->Right[i] = iRight; } ClbInfo->Right[i] = ClientRectHeader.right; // // Copy and parse the headings so that each column's heading // can be set. These can be new or old headings. // lstrcpy( Buffer, ClbInfo->Headings ); Heading = _tcstok( Buffer, HEADING_SEPARATOR ); hdi.mask = HDI_TEXT | HDI_FORMAT; hdi.fmt = HDF_STRING; for( i = 0; i < ClbInfo->Columns; i++ ) { hdi.pszText = (LPTSTR)Heading; Header_SetItem (ClbInfo->hWndHeader, i, &hdi); Heading = _tcstok( NULL, HEADING_SEPARATOR ); } return TRUE; }
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 } } } }